1
+ using System . Text . RegularExpressions ;
2
+
3
+ namespace PCL . Neo . Core . Utils ;
4
+
5
+ public static class Uuid
6
+ {
7
+ private const string DefaultUuid = "00000000-0000-0000-0000-000000000000" ;
8
+
9
+ public static string GenerateOfflineUuid ( string username )
10
+ {
11
+ if ( string . IsNullOrEmpty ( username ) || ! IsValidUsername ( username ) )
12
+ return DefaultUuid ;
13
+ var guid = new Guid ( MurmurHash3 . Hash ( username ) ) ;
14
+ return guid . ToString ( ) ;
15
+ }
16
+
17
+ public static bool IsValidUsername ( string username )
18
+ {
19
+ return ! string . IsNullOrEmpty ( username ) &&
20
+ username . Length >= 3 &&
21
+ username . Length <= 16 &&
22
+ Regex . IsMatch ( username , "^[a-zA-Z0-9_]+$" ) ;
23
+ }
24
+
25
+ // MurmurHash3算法实现
26
+ private static class MurmurHash3
27
+ {
28
+ public static byte [ ] Hash ( string str )
29
+ {
30
+ var bytes = System . Text . Encoding . UTF8 . GetBytes ( str ) ;
31
+ const uint seed = 144 ;
32
+ const uint c1 = 0xcc9e2d51 ;
33
+ const uint c2 = 0x1b873593 ;
34
+ uint h1 = seed ;
35
+ uint k1 ;
36
+ int len = bytes . Length ;
37
+ int i = 0 ;
38
+ for ( ; i + 4 <= len ; i += 4 )
39
+ {
40
+ k1 = ( uint ) ( ( bytes [ i ] & 0xFF ) |
41
+ ( ( bytes [ i + 1 ] & 0xFF ) << 8 ) |
42
+ ( ( bytes [ i + 2 ] & 0xFF ) << 16 ) |
43
+ ( ( bytes [ i + 3 ] & 0xFF ) << 24 ) ) ;
44
+ k1 *= c1 ;
45
+ k1 = RotateLeft ( k1 , 15 ) ;
46
+ k1 *= c2 ;
47
+ h1 ^= k1 ;
48
+ h1 = RotateLeft ( h1 , 13 ) ;
49
+ h1 = h1 * 5 + 0xe6546b64 ;
50
+ }
51
+ k1 = 0 ;
52
+ switch ( len & 3 )
53
+ {
54
+ case 3 : k1 ^= ( uint ) ( bytes [ i + 2 ] & 0xFF ) << 16 ; goto case 2 ;
55
+ case 2 : k1 ^= ( uint ) ( bytes [ i + 1 ] & 0xFF ) << 8 ; goto case 1 ;
56
+ case 1 :
57
+ k1 ^= ( uint ) ( bytes [ i ] & 0xFF ) ;
58
+ k1 *= c1 ;
59
+ k1 = RotateLeft ( k1 , 15 ) ;
60
+ k1 *= c2 ;
61
+ h1 ^= k1 ;
62
+ break ;
63
+ }
64
+ h1 ^= ( uint ) len ;
65
+ h1 = Fmix ( h1 ) ;
66
+ byte [ ] result = new byte [ 16 ] ;
67
+ BitConverter . GetBytes ( h1 ) . CopyTo ( result , 0 ) ;
68
+ BitConverter . GetBytes ( h1 ^ seed ) . CopyTo ( result , 4 ) ;
69
+ BitConverter . GetBytes ( seed ^ ( h1 >> 16 ) ) . CopyTo ( result , 8 ) ;
70
+ BitConverter . GetBytes ( seed ^ ( h1 << 8 ) ) . CopyTo ( result , 12 ) ;
71
+ return result ;
72
+ }
73
+ private static uint RotateLeft ( uint x , int r ) => ( x << r ) | ( x >> ( 32 - r ) ) ;
74
+ private static uint Fmix ( uint h )
75
+ {
76
+ h ^= h >> 16 ;
77
+ h *= 0x85ebca6b ;
78
+ h ^= h >> 13 ;
79
+ h *= 0xc2b2ae35 ;
80
+ h ^= h >> 16 ;
81
+ return h ;
82
+ }
83
+ }
84
+ }
0 commit comments