1
+ using System . Security . Cryptography ;
2
+ using System . Text ;
1
3
using System . Text . RegularExpressions ;
2
4
3
5
namespace PCL . Neo . Core . Utils ;
4
6
5
7
public static partial class Uuid // TODO: implement different way of genereate uuid
6
8
{
7
- private const string DefaultUuid = "00000000-0000-0000-0000-000000000000" ;
9
+ public enum UuidGenerateType
10
+ {
11
+ Guid ,
12
+ Standard ,
13
+ MurmurHash3
14
+ }
8
15
9
- public static string GenerateOfflineUuid ( string username )
16
+ /// <summary>
17
+ /// Generate UUID base on input username. If username is empty or invalid,
18
+ /// throw <see cref="ArgumentException"/>.
19
+ /// </summary>
20
+ /// <param name="username">Username to generate UUID.</param>
21
+ /// <param name="type">Type of UUID generation.</param>
22
+ /// <returns>Generated UUID.</returns>
23
+ /// <exception cref="ArgumentException">
24
+ /// If <paramref name="username"/> is invalid or empty.
25
+ /// </exception>
26
+ public static string GenerateUuid ( string username , UuidGenerateType type )
10
27
{
11
- if ( string . IsNullOrEmpty ( username ) || ! IsValidUsername ( username ) )
12
- return DefaultUuid ;
13
- var guid = new Guid ( MurmurHash3 . Hash ( username ) ) ;
14
- return guid . ToString ( ) ;
28
+ if ( string . IsNullOrEmpty ( username ) ||
29
+ ! IsValidUsername ( username ) )
30
+ {
31
+ throw new ArgumentException ( "Username is invalid." ) ;
32
+ }
33
+
34
+ var fullName = $ "OfflinePlayer:{ username } ";
35
+
36
+ var uuid = type switch
37
+ {
38
+ UuidGenerateType . Guid => new Guid ( MD5 . HashData ( Encoding . UTF8 . GetBytes ( fullName ) ) ) . ToString ( ) ,
39
+ UuidGenerateType . Standard => StadardVer ( fullName ) ,
40
+ UuidGenerateType . MurmurHash3 => new Guid ( MurmurHash3 . Hash ( fullName ) ) . ToString ( ) ,
41
+ _ => throw new ArgumentOutOfRangeException ( nameof ( type ) , type , null )
42
+ } ;
43
+
44
+ uuid = uuid . Replace ( "-" , string . Empty ) ;
45
+
46
+ return uuid ;
15
47
}
16
48
49
+ private static string StadardVer ( string name )
50
+ {
51
+ var hash = MD5 . HashData ( Encoding . UTF8 . GetBytes ( name ) ) ;
52
+
53
+ hash [ 6 ] = ( byte ) ( ( hash [ 6 ] & 0x0F ) | 0x30 ) ; // Version 3
54
+ hash [ 8 ] = ( byte ) ( ( hash [ 8 ] & 0x3F ) | 0x80 ) ; // Variant 1 (RFC 4122)
55
+
56
+ return new Uuids . Uuid ( hash ) . ToString ( ) ;
57
+ }
58
+
59
+ [ GeneratedRegex ( "^[a-zA-Z0-9_]+$" ) ]
60
+ private static partial Regex ValidUsernameRegex ( ) ;
61
+
17
62
public static bool IsValidUsername ( string username )
18
63
{
19
64
return ! string . IsNullOrEmpty ( username ) &&
@@ -22,11 +67,12 @@ public static bool IsValidUsername(string username)
22
67
}
23
68
24
69
// MurmurHash3算法实现
70
+
25
71
private static class MurmurHash3
26
72
{
27
73
public static byte [ ] Hash ( string str )
28
74
{
29
- var bytes = System . Text . Encoding . UTF8 . GetBytes ( str ) ;
75
+ var bytes = Encoding . UTF8 . GetBytes ( str ) ;
30
76
const uint seed = 144 ;
31
77
const uint c1 = 0xcc9e2d51 ;
32
78
const uint c2 = 0x1b873593 ;
@@ -80,7 +126,4 @@ private static uint Fmix(uint h)
80
126
return h ;
81
127
}
82
128
}
83
-
84
- [ GeneratedRegex ( "^[a-zA-Z0-9_]+$" ) ]
85
- private static partial Regex ValidUsernameRegex ( ) ;
86
129
}
0 commit comments