using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using DnsClient;
using Masuit.Tools.Strings;
namespace Masuit.Tools
{
public static partial class StringExtensions
{
///
/// 字符串转时间
///
///
///
public static DateTime ToDateTime(this string value)
{
DateTime.TryParse(value, out var result);
return result;
}
///
/// 字符串转Guid
///
///
///
public static Guid ToGuid(this string s)
{
return Guid.Parse(s);
}
///
/// 根据正则替换
///
///
/// 正则表达式
/// 新内容
///
public static string Replace(this string input, Regex regex, string replacement)
{
return regex.Replace(input, replacement);
}
///
/// 生成唯一短字符串
///
///
/// 可用字符数数量,0-9,a-z,A-Z
///
public static string CreateShortToken(this string str, byte chars = 36)
{
var nf = new NumberFormater(chars);
return nf.ToString((DateTime.Now.Ticks - 630822816000000000) * 100 + Stopwatch.GetTimestamp() % 100);
}
///
/// 任意进制转十进制
///
///
/// 进制
///
public static long ToBinary(this string str, int bin)
{
var nf = new NumberFormater(bin);
return nf.FromString(str);
}
///
/// 任意进制转大数十进制
///
///
/// 进制
///
public static BigInteger ToBinaryBig(this string str, int bin)
{
var nf = new NumberFormater(bin);
return nf.FromStringBig(str);
}
#region 检测字符串中是否包含列表中的关键词
///
/// 检测字符串中是否包含列表中的关键词
///
/// 源字符串
/// 关键词列表
/// 忽略大小写
///
public static bool Contains(this string s, IEnumerable keys, bool ignoreCase = true)
{
if (!keys.Any() || string.IsNullOrEmpty(s))
{
return false;
}
if (ignoreCase)
{
return Regex.IsMatch(s, string.Join("|", keys), RegexOptions.IgnoreCase);
}
return Regex.IsMatch(s, string.Join("|", keys));
}
///
/// 判断是否包含符号
///
///
///
///
public static bool ContainsSymbol(this string str, params string[] symbols)
{
return str switch
{
null => false,
string a when string.IsNullOrEmpty(a) => false,
string a when a == string.Empty => false,
_ => symbols.Any(t => str.Contains(t))
};
}
#endregion 检测字符串中是否包含列表中的关键词
///
/// 判断字符串是否为空或""
///
///
///
public static bool IsNullOrEmpty(this string s)
{
return string.IsNullOrEmpty(s);
}
///
/// 字符串掩码
///
/// 字符串
/// 掩码符
///
public static string Mask(this string s, char mask = '*')
{
if (string.IsNullOrWhiteSpace(s?.Trim()))
{
return s;
}
s = s.Trim();
string masks = mask.ToString().PadLeft(4, mask);
return s.Length switch
{
_ when s.Length >= 11 => Regex.Replace(s, @"(\w{3})\w*(\w{4})", $"$1{masks}$2"),
_ when s.Length == 10 => Regex.Replace(s, @"(\w{3})\w*(\w{3})", $"$1{masks}$2"),
_ when s.Length == 9 => Regex.Replace(s, @"(\w{2})\w*(\w{3})", $"$1{masks}$2"),
_ when s.Length == 8 => Regex.Replace(s, @"(\w{2})\w*(\w{2})", $"$1{masks}$2"),
_ when s.Length == 7 => Regex.Replace(s, @"(\w{1})\w*(\w{2})", $"$1{masks}$2"),
_ when s.Length >= 2 && s.Length < 7 => Regex.Replace(s, @"(\w{1})\w*(\w{1})", $"$1{masks}$2"),
_ => s + masks
};
}
#region Email
///
/// 匹配Email
///
/// 源字符串
/// 是否验证有效性
/// 匹配对象;是否匹配成功,若返回true,则会得到一个Match对象,否则为null
public static (bool isMatch, Match match) MatchEmail(this string s, bool valid = false)
{
if (string.IsNullOrEmpty(s) || s.Length < 7)
{
return (false, null);
}
Match match = Regex.Match(s, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
var isMatch = match.Success;
if (isMatch && valid)
{
var nslookup = new LookupClient();
var query = nslookup.Query(s.Split('@')[1], QueryType.MX).Answers.MxRecords().SelectMany(r => Dns.GetHostAddresses(r.Exchange.Value)).ToList();
isMatch = query.Any(ip => !ip.IsPrivateIP());
}
return (isMatch, match);
}
///
/// 邮箱掩码
///
/// 邮箱
/// 掩码
///
public static string MaskEmail(this string s, char mask = '*')
{
return !MatchEmail(s).isMatch ? s : s.Replace(s.Substring(0, s.LastIndexOf("@")), Mask(s.Substring(0, s.LastIndexOf("@")), mask));
}
#endregion Email
#region 匹配完整的URL
///
/// 匹配完整格式的URL
///
/// 源字符串
/// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null
/// 匹配对象
public static Uri MatchUrl(this string s, out bool isMatch)
{
try
{
var uri = new Uri(s);
isMatch = Dns.GetHostAddresses(uri.Host).Any(ip => !ip.IsPrivateIP());
return uri;
}
catch
{
isMatch = false;
return null;
}
}
///
/// 匹配完整格式的URL
///
/// 源字符串
/// 是否匹配成功
public static bool MatchUrl(this string s)
{
MatchUrl(s, out var isMatch);
return isMatch;
}
#endregion 匹配完整的URL
#region 权威校验身份证号码
///
/// 根据GB11643-1999标准权威校验中国身份证号码的合法性
///
/// 源字符串
/// 是否匹配成功
public static bool MatchIdentifyCard(this string s)
{
string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
if (s.Length == 18)
{
if (long.TryParse(s.Remove(17), out var n) == false || n < Math.Pow(10, 16) || long.TryParse(s.Replace('x', '0').Replace('X', '0'), out n) == false)
{
return false; //数字验证
}
if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1)
{
return false; //省份验证
}
string birth = s.Substring(6, 8).Insert(6, "-").Insert(4, "-");
if (!DateTime.TryParse(birth, out _))
{
return false; //生日验证
}
string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
char[] ai = s.Remove(17).ToCharArray();
int sum = 0;
for (int i = 0 ; i < 17 ; i++)
{
sum += wi[i].ToInt32() * ai[i].ToString().ToInt32();
}
Math.DivRem(sum, 11, out var y);
return arrVarifyCode[y] == s.Substring(17, 1).ToLower();
}
if (s.Length == 15)
{
if (long.TryParse(s, out var n) == false || n < Math.Pow(10, 14))
{
return false; //数字验证
}
if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1)
{
return false; //省份验证
}
string birth = s.Substring(6, 6).Insert(4, "-").Insert(2, "-");
return DateTime.TryParse(birth, out _);
}
return false;
}
#endregion 权威校验身份证号码
#region IP地址
///
/// 校验IP地址的正确性,同时支持IPv4和IPv6
///
/// 源字符串
/// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null
/// 匹配对象
public static IPAddress MatchInetAddress(this string s, out bool isMatch)
{
isMatch = IPAddress.TryParse(s, out var ip);
return ip;
}
///
/// 校验IP地址的正确性,同时支持IPv4和IPv6
///
/// 源字符串
/// 是否匹配成功
public static bool MatchInetAddress(this string s)
{
MatchInetAddress(s, out var success);
return success;
}
///
/// IP地址转换成数字
///
/// IP地址
/// 数字,输入无效IP地址返回0
public static uint IPToID(this string addr)
{
if (!IPAddress.TryParse(addr, out var ip))
{
return 0;
}
byte[] bInt = ip.GetAddressBytes();
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bInt);
}
return BitConverter.ToUInt32(bInt, 0);
}
///
/// 判断IP是否是私有地址
///
///
///
public static bool IsPrivateIP(this string ip)
{
if (MatchInetAddress(ip))
{
return IPAddress.Parse(ip).IsPrivateIP();
}
throw new ArgumentException(ip + "不是一个合法的ip地址");
}
///
/// 判断IP地址在不在某个IP地址段
///
/// 需要判断的IP地址
/// 起始地址
/// 结束地址
///
public static bool IpAddressInRange(this string input, string begin, string ends)
{
uint current = input.IPToID();
return current >= begin.IPToID() && current <= ends.IPToID();
}
#endregion IP地址
#region 校验手机号码的正确性
///
/// 匹配手机号码
///
/// 源字符串
/// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null
/// 匹配对象
public static Match MatchPhoneNumber(this string s, out bool isMatch)
{
if (string.IsNullOrEmpty(s))
{
isMatch = false;
return null;
}
Match match = Regex.Match(s, @"^((1[3,5,6,8][0-9])|(14[5,7])|(17[0,1,3,6,7,8])|(19[8,9]))\d{8}$");
isMatch = match.Success;
return isMatch ? match : null;
}
///
/// 匹配手机号码
///
/// 源字符串
/// 是否匹配成功
public static bool MatchPhoneNumber(this string s)
{
MatchPhoneNumber(s, out bool success);
return success;
}
#endregion 校验手机号码的正确性
#region Url
///
/// 判断url是否是外部地址
///
///
///
public static bool IsExternalAddress(this string url)
{
var uri = new Uri(url);
switch (uri.HostNameType)
{
case UriHostNameType.Dns:
var ipHostEntry = Dns.GetHostEntry(uri.DnsSafeHost);
if (ipHostEntry.AddressList.Where(ipAddress => ipAddress.AddressFamily == AddressFamily.InterNetwork).Any(ipAddress => !ipAddress.IsPrivateIP()))
{
return true;
}
break;
case UriHostNameType.IPv4:
return !IPAddress.Parse(uri.DnsSafeHost).IsPrivateIP();
}
return false;
}
#endregion Url
///
/// 转换成字节数组
///
///
///
public static byte[] ToByteArray(this string @this)
{
return Activator.CreateInstance().GetBytes(@this);
}
#region Crc32
///
/// 获取字符串crc32签名
///
///
///
public static string Crc32(this string s)
{
return string.Join(string.Empty, new Security.Crc32().ComputeHash(Encoding.UTF8.GetBytes(s)).Select(b => b.ToString("x2")));
}
///
/// 获取字符串crc64签名
///
///
///
public static string Crc64(this string s)
{
return string.Join(string.Empty, new Security.Crc64().ComputeHash(Encoding.UTF8.GetBytes(s)).Select(b => b.ToString("x2")));
}
#endregion Crc32
}
}