1
+ var cnBase58 = ( function ( ) {
2
+ var b58 = { } ;
3
+
4
+ var alphabet_str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ;
5
+ var alphabet = [ ] ;
6
+ for ( var i = 0 ; i < alphabet_str . length ; i ++ ) {
7
+ alphabet . push ( alphabet_str . charCodeAt ( i ) ) ;
8
+ }
9
+ var encoded_block_sizes = [ 0 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 ] ;
10
+
11
+ var alphabet_size = alphabet . length ;
12
+ var full_block_size = 8 ;
13
+ var full_encoded_block_size = 11 ;
14
+
15
+ var UINT64_MAX = new JSBigInt ( 2 ) . pow ( 64 ) ;
16
+
17
+ function hextobin ( hex ) {
18
+ if ( hex . length % 2 !== 0 ) throw "Hex string has invalid length!" ;
19
+ var res = new Uint8Array ( hex . length / 2 ) ;
20
+ for ( var i = 0 ; i < hex . length / 2 ; ++ i ) {
21
+ res [ i ] = parseInt ( hex . slice ( i * 2 , i * 2 + 2 ) , 16 ) ;
22
+ }
23
+ return res ;
24
+ }
25
+
26
+ function bintohex ( bin ) {
27
+ var out = [ ] ;
28
+ for ( var i = 0 ; i < bin . length ; ++ i ) {
29
+ out . push ( ( "0" + bin [ i ] . toString ( 16 ) ) . slice ( - 2 ) ) ;
30
+ }
31
+ return out . join ( "" ) ;
32
+ }
33
+
34
+ function strtobin ( str ) {
35
+ var res = new Uint8Array ( str . length ) ;
36
+ for ( var i = 0 ; i < str . length ; i ++ ) {
37
+ res [ i ] = str . charCodeAt ( i ) ;
38
+ }
39
+ return res ;
40
+ }
41
+
42
+ function bintostr ( bin ) {
43
+ var out = [ ] ;
44
+ for ( var i = 0 ; i < bin . length ; i ++ ) {
45
+ out . push ( String . fromCharCode ( bin [ i ] ) ) ;
46
+ }
47
+ return out . join ( "" ) ;
48
+ }
49
+
50
+ function uint8_be_to_64 ( data ) {
51
+ if ( data . length < 1 || data . length > 8 ) {
52
+ throw "Invalid input length" ;
53
+ }
54
+ var res = JSBigInt . ZERO ;
55
+ var twopow8 = new JSBigInt ( 2 ) . pow ( 8 ) ;
56
+ var i = 0 ;
57
+ switch ( 9 - data . length ) {
58
+ case 1 :
59
+ res = res . add ( data [ i ++ ] ) ;
60
+ case 2 :
61
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
62
+ case 3 :
63
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
64
+ case 4 :
65
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
66
+ case 5 :
67
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
68
+ case 6 :
69
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
70
+ case 7 :
71
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
72
+ case 8 :
73
+ res = res . multiply ( twopow8 ) . add ( data [ i ++ ] ) ;
74
+ break ;
75
+ default :
76
+ throw "Impossible condition" ;
77
+ }
78
+ return res ;
79
+ }
80
+
81
+ function uint64_to_8be ( num , size ) {
82
+ var res = new Uint8Array ( size ) ;
83
+ if ( size < 1 || size > 8 ) {
84
+ throw "Invalid input length" ;
85
+ }
86
+ var twopow8 = new JSBigInt ( 2 ) . pow ( 8 ) ;
87
+ for ( var i = size - 1 ; i >= 0 ; i -- ) {
88
+ res [ i ] = num . remainder ( twopow8 ) . toJSValue ( ) ;
89
+ num = num . divide ( twopow8 ) ;
90
+ }
91
+ return res ;
92
+ }
93
+
94
+ b58 . encode_block = function ( data , buf , index ) {
95
+ if ( data . length < 1 || data . length > full_encoded_block_size ) {
96
+ throw "Invalid block length: " + data . length ;
97
+ }
98
+ var num = uint8_be_to_64 ( data ) ;
99
+ var i = encoded_block_sizes [ data . length ] - 1 ;
100
+ // while num > 0
101
+ while ( num . compare ( 0 ) === 1 ) {
102
+ var div = num . divRem ( alphabet_size ) ;
103
+ // remainder = num % alphabet_size
104
+ var remainder = div [ 1 ] ;
105
+ // num = num / alphabet_size
106
+ num = div [ 0 ] ;
107
+ buf [ index + i ] = alphabet [ remainder . toJSValue ( ) ] ;
108
+ i -- ;
109
+ }
110
+ return buf ;
111
+ } ;
112
+
113
+ b58 . encode = function ( hex ) {
114
+ var data = hextobin ( hex ) ;
115
+ if ( data . length === 0 ) {
116
+ return "" ;
117
+ }
118
+ var full_block_count = Math . floor ( data . length / full_block_size ) ;
119
+ var last_block_size = data . length % full_block_size ;
120
+ var res_size = full_block_count * full_encoded_block_size + encoded_block_sizes [ last_block_size ] ;
121
+
122
+ var res = new Uint8Array ( res_size ) ;
123
+ var i ;
124
+ for ( i = 0 ; i < res_size ; ++ i ) {
125
+ res [ i ] = alphabet [ 0 ] ;
126
+ }
127
+ for ( i = 0 ; i < full_block_count ; i ++ ) {
128
+ res = b58 . encode_block ( data . subarray ( i * full_block_size , i * full_block_size + full_block_size ) , res , i * full_encoded_block_size ) ;
129
+ }
130
+ if ( last_block_size > 0 ) {
131
+ res = b58 . encode_block ( data . subarray ( full_block_count * full_block_size , full_block_count * full_block_size + last_block_size ) , res , full_block_count * full_encoded_block_size )
132
+ }
133
+ return bintostr ( res ) ;
134
+ } ;
135
+
136
+ b58 . decode_block = function ( data , buf , index ) {
137
+ if ( data . length < 1 || data . length > full_encoded_block_size ) {
138
+ throw "Invalid block length: " + data . length ;
139
+ }
140
+
141
+ var res_size = encoded_block_sizes . indexOf ( data . length ) ;
142
+ if ( res_size <= 0 ) {
143
+ throw "Invalid block size" ;
144
+ }
145
+ var res_num = new JSBigInt ( 0 ) ;
146
+ var order = new JSBigInt ( 1 ) ;
147
+ for ( var i = data . length - 1 ; i >= 0 ; i -- ) {
148
+ var digit = alphabet . indexOf ( data [ i ] ) ;
149
+ if ( digit < 0 ) {
150
+ throw "Invalid symbol" ;
151
+ }
152
+ var product = order . multiply ( digit ) . add ( res_num ) ;
153
+ // if product > UINT64_MAX
154
+ if ( product . compare ( UINT64_MAX ) === 1 ) {
155
+ throw "Overflow" ;
156
+ }
157
+ res_num = product ;
158
+ order = order . multiply ( alphabet_size ) ;
159
+ }
160
+ if ( res_size < full_block_size && ( new JSBigInt ( 2 ) . pow ( 8 * res_size ) . compare ( res_num ) <= 0 ) ) {
161
+ throw "Overflow 2" ;
162
+ }
163
+ buf . set ( uint64_to_8be ( res_num , res_size ) , index ) ;
164
+ return buf ;
165
+ } ;
166
+
167
+ b58 . decode = function ( enc ) {
168
+ enc = strtobin ( enc ) ;
169
+ if ( enc . length === 0 ) {
170
+ return "" ;
171
+ }
172
+ var full_block_count = Math . floor ( enc . length / full_encoded_block_size ) ;
173
+ var last_block_size = enc . length % full_encoded_block_size ;
174
+ var last_block_decoded_size = encoded_block_sizes . indexOf ( last_block_size ) ;
175
+ if ( last_block_decoded_size < 0 ) {
176
+ throw "Invalid encoded length" ;
177
+ }
178
+ var data_size = full_block_count * full_block_size + last_block_decoded_size ;
179
+ var data = new Uint8Array ( data_size ) ;
180
+ for ( var i = 0 ; i < full_block_count ; i ++ ) {
181
+ data = b58 . decode_block ( enc . subarray ( i * full_encoded_block_size , i * full_encoded_block_size + full_encoded_block_size ) , data , i * full_block_size ) ;
182
+ }
183
+ if ( last_block_size > 0 ) {
184
+ data = b58 . decode_block ( enc . subarray ( full_block_count * full_encoded_block_size , full_block_count * full_encoded_block_size + last_block_size ) , data , full_block_count * full_block_size ) ;
185
+ }
186
+ return bintohex ( data ) ;
187
+ } ;
188
+
189
+ return b58 ;
190
+ } ) ( ) ;
0 commit comments