1 /// <summary>
2 /// 短链生成
3 /// </summary>
4 public class ShortUrlBuilder
5 {
6 private static readonly string[] Chars =
7 { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" ,
8
9 "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" ,
10
11 "u" , "v" , "w" , "x" , "y" , "z" , "0" , "1" , "2" , "3" , "4" , "5" ,
12
13 "6" , "7" , "8" , "9" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" ,
14
15 "I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
16
17 "U" , "V" , "W" , "X" , "Y" , "Z"
18 };
19
20 /// <summary>
21 /// 生成指定URL的摘要
22 /// </summary>
23 /// <param name="url">URL</param>
24 /// <returns>短链列表,任取一个存储就行。</returns>
25 public static List<string> Build(string url)
26 {
27 var shortUrls = new List<string>();
28 if (url == null)
29 {
30 return shortUrls;
31 }
32 var hash = GetMd5(url);
33 //将32个字符的md5码分成4段处理,每段8个字符
34 for (int i = 0; i < 4; i++)
35 {
36
37 int offset = i * 8;
38
39 string sub = hash.Substring(offset, 8);
40
41 long sub16 = long.Parse(sub, NumberStyles.HexNumber); //将sub当作一个16进制的数,转成long
42
43 // & 0X3FFFFFFF,去掉最前面的2位,只留下30位
44 sub16 &= 0X3FFFFFFF;
45
46 StringBuilder sb = new StringBuilder();
47 //将剩下的30位分6段处理,每段5位
48 for (int j = 0; j < 6; j++)
49 {
50 //得到一个 <= 61的数字
51 long t = sub16 & 0x0000003D;
52 sb.Append(Chars[(int)t]);
53
54 sub16 >>= 5; //将sub16右移5位
55 }
56
57 shortUrls.Add(sb.ToString());
58 }
59 return shortUrls;
60 }
61
62 /// <summary>
63 /// MD5加密
64 /// </summary>
65 /// <param name="myString">原始字符串</param>
66 /// <param name="salt">盐</param>
67 /// <returns></returns>
68 private static string GetMd5(string myString, string salt = "")
69 {
70 if (myString != null)
71 {
72 var array = myString.ToCharArray();
73 Array.Reverse(array);
74 myString = $"{new string(array)}+{{{salt}}}";
75
76 #if DEBUG
77 Debugger.Log(1, "2", $"自定义消息:{myString}\r\n");
78 #endif
79 MD5 md5 = MD5.Create();
80 byte[] bs = Encoding.UTF8.GetBytes(myString);
81 byte[] hs = md5.ComputeHash(bs);
82 StringBuilder sb = new StringBuilder();
83 foreach (byte b in hs)
84 {
85 // 以十六进制格式格式化
86 sb.Append(b.ToString("x2"));
87 }
88 return sb.ToString();
89
90 }
91 return null;
92 }
93 }