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 System.Threading.Tasks; using DNS.Client; using DNS.Protocol; namespace System { /// /// String extensions. /// public static class StringExtensions { /// /// Converts a hex string into a byte array. /// /// The hex encoded string. /// A delimiter between the bytes (e.g. for MAC address). /// The bytes. public static IEnumerable 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); } /// /// Converts a byte collection into a hex string. /// /// The bytes. /// A delimiter to set between the bytes (e.g. for MAC address). /// The hex encoded string. public static string BytesToHex(this IEnumerable bytes, string delimiter = "") { if (bytes?.Any() != true) return null; return string.Join(delimiter, bytes.Select(b => b.ToString("x2"))); } /// /// Encodes a string to the hexadecimal system (base 16). /// /// The string to encode hexadecimal. /// The text encoding to use (default: ) /// public static string HexEncode(this string str, Encoding encoding = null) { if (string.IsNullOrEmpty(str)) return str; return (encoding ?? Encoding.Default).GetBytes(str).BytesToHex(); } /// /// Decodes a string from the hexadecimal system (base 16). /// /// The hexadecimal encoded string to decode. /// The text encoding to use (default: ) /// public static string HexDecode(this string str, Encoding encoding = null) { if (string.IsNullOrEmpty(str)) return str; return (encoding ?? Encoding.Default).GetString(str.HexToBytes().ToArray()); } /// /// Encodes a string to base64. /// /// The string to encode with base64. /// The text encoding to use (default: ) /// public static string Base64Encode(this string str, Encoding encoding = null) => Convert.ToBase64String((encoding ?? Encoding.Default).GetBytes(str)); /// /// Decodes a string from base64. /// /// The base64 encoded string to decode. /// The text encoding to use (default: ) /// public static string Base64Decode(this string str, Encoding encoding = null) => (encoding ?? Encoding.Default).GetString(Convert.FromBase64String(str)); /// /// Replaces the search substring with the replacement when it was found at the beginning of the string. /// /// The string. /// The searched substring. /// The replacement. /// public static string ReplaceStart(this string str, string search, string replacement) { if (str.StartsWith(search)) return replacement + str.Substring(search.Length); return str; } /// /// Replaces the search substring with the replacement when it was found at the end of the string. /// /// The string. /// The searched substring. /// The replacement. /// 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; } /// /// Parses a to a using culture "de" or invariant. /// /// The string to parse. /// 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); } /// /// Checks whether the given is a valid . /// /// /// You can enhance the check by requesting the MX record of the domain. /// /// The email address as string to validate. /// A value indicating whether to resolve a MX record (Google DNS is used). /// true when the email address is valid, other wise false. public static bool IsValidEmailAddress(this string email, bool checkRecordExists = false) => email.IsValidEmailAddress(checkRecordExists ? new[] { new IPEndPoint(IPAddress.Parse("8.8.8.8"), 53) } : null); /// /// Checks whether the given is a valid . /// /// /// The check is enhanced by a request for MX records on the defined . /// /// The email address as string to validate. /// A list of s of nameservers. /// true when the email address is valid, other wise false. public static bool IsValidEmailAddress(this string email, IEnumerable nameservers) { try { var mailAddress = new MailAddress(email); bool isValid = mailAddress.Address == email; if (isValid && nameservers?.Any() == true) { bool exists = false; foreach (var nameserver in nameservers) { var client = new DnsClient(nameserver); var waitTask = Task.Run(async () => await client.Resolve(mailAddress.Host, RecordType.MX)); waitTask.Wait(); var response = waitTask.Result; waitTask.Dispose(); if (response.ResponseCode != ResponseCode.NoError) continue; exists = response.AnswerRecords .Where(r => r.Type == RecordType.MX) .Any(); break; } isValid &= exists; } return isValid; } catch { return false; } } } }