1+ using System . Security . Cryptography ;
2+ using System . Text ;
13using System . Text . RegularExpressions ;
24
35namespace PCL . Neo . Core . Utils ;
46
57public static partial class Uuid // TODO: implement different way of genereate uuid
68{
7- private const string DefaultUuid = "00000000-0000-0000-0000-000000000000" ;
9+ public enum UuidGenerateType
10+ {
11+ Guid ,
12+ Standard ,
13+ MurmurHash3
14+ }
815
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 )
1027 {
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 ;
1547 }
1648
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+
1762 public static bool IsValidUsername ( string username )
1863 {
1964 return ! string . IsNullOrEmpty ( username ) &&
@@ -22,11 +67,12 @@ public static bool IsValidUsername(string username)
2267 }
2368
2469 // MurmurHash3算法实现
70+
2571 private static class MurmurHash3
2672 {
2773 public static byte [ ] Hash ( string str )
2874 {
29- var bytes = System . Text . Encoding . UTF8 . GetBytes ( str ) ;
75+ var bytes = Encoding . UTF8 . GetBytes ( str ) ;
3076 const uint seed = 144 ;
3177 const uint c1 = 0xcc9e2d51 ;
3278 const uint c2 = 0x1b873593 ;
@@ -80,7 +126,4 @@ private static uint Fmix(uint h)
80126 return h ;
81127 }
82128 }
83-
84- [ GeneratedRegex ( "^[a-zA-Z0-9_]+$" ) ]
85- private static partial Regex ValidUsernameRegex ( ) ;
86129}
0 commit comments