1
0
Files
common/AMWD.Common/Extensions/StringExtensions.cs

190 lines
6.8 KiB
C#

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;
using DnsClient;
namespace System
{
/// <summary>
/// String extensions.
/// </summary>
public static class StringExtensions
{
/// <summary>
/// Converts a hex string into a byte array.
/// </summary>
/// <param name="hexString">The hex encoded string.</param>
/// <param name="delimiter">A delimiter between the bytes (e.g. for MAC address).</param>
/// <returns>The bytes.</returns>
public static IEnumerable<byte> HexToBytes(this string hexString, string delimiter = "")
{
if (string.IsNullOrWhiteSpace(hexString))
yield break;
string str = string.IsNullOrEmpty(delimiter) ? hexString : hexString.Replace(delimiter, "");
if (str.Length % 2 == 1)
yield break;
if (Regex.IsMatch(str, "[^0-9a-fA-F]"))
yield break;
for (int i = 0; i < str.Length; i += 2)
yield return Convert.ToByte(str.Substring(i, 2), 16);
}
/// <summary>
/// Converts a byte collection into a hex string.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="delimiter">A delimiter to set between the bytes (e.g. for MAC address).</param>
/// <returns>The hex encoded string.</returns>
public static string BytesToHex(this IEnumerable<byte> bytes, string delimiter = "")
{
if (bytes?.Any() != true)
return null;
return string.Join(delimiter, bytes.Select(b => b.ToString("x2")));
}
/// <summary>
/// Encodes a string to the hexadecimal system (base 16).
/// </summary>
/// <param name="str">The string to encode hexadecimal.</param>
/// <param name="encoding">The text encoding to use (default: <see cref="Encoding.Default"/>)</param>
/// <returns></returns>
public static string HexEncode(this string str, Encoding encoding = null)
{
if (string.IsNullOrEmpty(str))
return str;
return (encoding ?? Encoding.Default).GetBytes(str).BytesToHex();
}
/// <summary>
/// Decodes a string from the hexadecimal system (base 16).
/// </summary>
/// <param name="str">The hexadecimal encoded string to decode.</param>
/// <param name="encoding">The text encoding to use (default: <see cref="Encoding.Default"/>)</param>
/// <returns></returns>
public static string HexDecode(this string str, Encoding encoding = null)
{
if (string.IsNullOrEmpty(str))
return str;
return (encoding ?? Encoding.Default).GetString(str.HexToBytes().ToArray());
}
/// <summary>
/// Encodes a string to base64.
/// </summary>
/// <param name="str">The string to encode with base64.</param>
/// <param name="encoding">The text encoding to use (default: <see cref="Encoding.Default"/>)</param>
/// <returns></returns>
public static string Base64Encode(this string str, Encoding encoding = null)
=> Convert.ToBase64String((encoding ?? Encoding.Default).GetBytes(str));
/// <summary>
/// Decodes a string from base64.
/// </summary>
/// <param name="str">The base64 encoded string to decode.</param>
/// <param name="encoding">The text encoding to use (default: <see cref="Encoding.Default"/>)</param>
/// <returns></returns>
public static string Base64Decode(this string str, Encoding encoding = null)
=> (encoding ?? Encoding.Default).GetString(Convert.FromBase64String(str));
/// <summary>
/// Replaces the search substring with the replacement when it was found at the beginning of the string.
/// </summary>
/// <param name="str">The string.</param>
/// <param name="search">The searched substring.</param>
/// <param name="replacement">The replacement.</param>
/// <returns></returns>
public static string ReplaceStart(this string str, string search, string replacement)
{
if (str.StartsWith(search))
return replacement + str.Substring(search.Length);
return str;
}
/// <summary>
/// Replaces the search substring with the replacement when it was found at the end of the string.
/// </summary>
/// <param name="str">The string.</param>
/// <param name="search">The searched substring.</param>
/// <param name="replacement">The replacement.</param>
/// <returns></returns>
public static string ReplaceEnd(this string str, string search, string replacement)
{
if (str.EndsWith(search))
return str.Substring(0, str.Length - search.Length) + replacement;
return str;
}
/// <summary>
/// Parses a <see cref="string"/> to a <see cref="decimal"/> using culture "de" or invariant.
/// </summary>
/// <param name="decString">The string to parse.</param>
/// <returns></returns>
public static decimal ParseDecimal(this string decString)
{
int dotIndex = decString.LastIndexOf('.');
int commaIndex = decString.LastIndexOf(',');
var culture = dotIndex < commaIndex ? new CultureInfo("de-DE") : CultureInfo.InvariantCulture;
return decimal.Parse(decString, culture);
}
/// <summary>
/// Checks whether the given <see cref="string"/> is a valid <see cref="MailAddress"/>.
/// </summary>
/// <remarks>
/// You can enhance the check by requesting the MX record of the domain.
/// </remarks>
/// <param name="email">The email address as string to validate.</param>
/// <param name="checkRecordExists">A value indicating whether to resolve a MX record.</param>
/// <returns><c>true</c> when the email address is valid, other wise <c>false</c>.</returns>
public static bool IsValidEmailAddress(this string email, bool checkRecordExists = false)
=> email.IsValidEmailAddress(checkRecordExists ? new LookupClient() : null);
/// <summary>
/// Checks whether the given <see cref="string"/> is a valid <see cref="MailAddress"/>.
/// </summary>
/// <remarks>
/// The check is enhanced by a request for MX records on the defined <paramref name="nameservers"/>.
/// </remarks>
/// <param name="email">The email address as string to validate.</param>
/// <param name="nameservers">A list of <see cref="IPEndPoint"/>s of nameservers.</param>
/// <returns><c>true</c> when the email address is valid, other wise <c>false</c>.</returns>
public static bool IsValidEmailAddress(this string email, IEnumerable<IPEndPoint> nameservers)
=> email.IsValidEmailAddress(new LookupClient(nameservers.ToArray()));
private static bool IsValidEmailAddress(this string email, LookupClient lookupClient)
{
try
{
var mailAddress = new MailAddress(email);
bool isValid = mailAddress.Address == email;
if (isValid && lookupClient != null)
{
var result = lookupClient.Query(mailAddress.Host, QueryType.MX);
isValid &= result.Answers.MxRecords().Any();
}
return isValid;
}
catch
{
return false;
}
}
}
}