11import assert from 'assert' ;
22import v7 from '../../src/v7.js' ;
3+ import stringify from '../../src/stringify.js' ;
34
45/**
56 * fixture bit layout:
@@ -154,7 +155,7 @@ describe('v7', () => {
154155 seq,
155156 } ) ;
156157
157- assert . strictEqual ( uuid . substr ( 0 , 25 ) , '017f22e2-79b0-7fff -bfff-f' ) ;
158+ assert . strictEqual ( uuid . substr ( 0 , 25 ) , '017f22e2-79b0-7dff -bfff-f' ) ;
158159 } ) ;
159160
160161 test ( 'internal seq is reset upon timestamp change' , ( ) => {
@@ -169,4 +170,46 @@ describe('v7', () => {
169170
170171 assert ( uuid . indexOf ( 'fff' ) !== 15 ) ;
171172 } ) ;
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+ } ) ;
172215} ) ;
0 commit comments