1
1
import assert from 'assert' ;
2
2
import v7 from '../../src/v7.js' ;
3
+ import stringify from '../../src/stringify.js' ;
3
4
4
5
/**
5
6
* fixture bit layout:
@@ -154,7 +155,7 @@ describe('v7', () => {
154
155
seq,
155
156
} ) ;
156
157
157
- assert . strictEqual ( uuid . substr ( 0 , 25 ) , '017f22e2-79b0-7fff -bfff-f' ) ;
158
+ assert . strictEqual ( uuid . substr ( 0 , 25 ) , '017f22e2-79b0-7dff -bfff-f' ) ;
158
159
} ) ;
159
160
160
161
test ( 'internal seq is reset upon timestamp change' , ( ) => {
@@ -169,4 +170,46 @@ describe('v7', () => {
169
170
170
171
assert ( uuid . indexOf ( 'fff' ) !== 15 ) ;
171
172
} ) ;
173
+
174
+ test ( 'flipping bits changes the result' , ( ) => {
175
+ // convert uint8array to BigInt (BE)
176
+ const asBigInt = ( buf ) => buf . reduce ( ( acc , v ) => ( acc << 8n ) | BigInt ( v ) , 0n ) ;
177
+
178
+ // convert the given number of bits (LE) to number
179
+ const asNumber = ( bits , data ) => Number ( BigInt . asUintN ( bits , data ) ) ;
180
+
181
+ // flip the nth bit (BE) in a BigInt
182
+ const flip = ( data , n ) => data ^ ( 1n << BigInt ( 127 - n ) ) ;
183
+
184
+ // Extract v7 `options` from a (BigInt) UUID
185
+ const optionsFrom = ( data ) => {
186
+ const ms = asNumber ( 48 , data >> ( 128n - 48n ) ) ;
187
+ const hi = asNumber ( 12 , data >> ( 43n + 19n + 2n ) ) ;
188
+ const lo = asNumber ( 19 , data >> 43n ) ;
189
+ const r = BigInt . asUintN ( 43 , data ) ;
190
+ return {
191
+ msecs : ms ,
192
+ seq : ( hi << 19 ) | lo ,
193
+ random : [
194
+ ...Array ( 10 ) . fill ( 0 ) ,
195
+ ...Array ( 6 )
196
+ . fill ( 0 )
197
+ . map ( ( _ , i ) => asNumber ( 8 , r >> ( BigInt ( i ) * 8n ) ) )
198
+ . reverse ( ) ,
199
+ ] ,
200
+ } ;
201
+ } ;
202
+ const buf = new Uint8Array ( 16 ) ;
203
+ const data = asBigInt ( v7 ( { } , buf ) ) ;
204
+ const id = stringify ( buf ) ;
205
+ const reserved = [ 48 , 49 , 50 , 51 , 64 , 65 ] ;
206
+ for ( let i = 0 ; i < 128 ; ++ i ) {
207
+ if ( reserved . includes ( i ) ) {
208
+ continue ; // skip bits used for version and variant
209
+ }
210
+ const flipped = flip ( data , i ) ;
211
+ assert . strictEqual ( asBigInt ( v7 ( optionsFrom ( flipped ) , buf ) ) , flipped , i ) ;
212
+ assert . notStrictEqual ( stringify ( buf ) , id ) ;
213
+ }
214
+ } ) ;
172
215
} ) ;
0 commit comments