11import lcm from './lcm'
22
33class CharSet {
4- constructor ( chars , ndxFn ) {
4+ constructor ( chars ) {
5+ let bitsPerByte = 8
6+
57 this . chars = chars
6- this . ndxFn = ndxFn
78 this . bitsPerChar = Math . floor ( Math . log2 ( chars . length ) )
89 if ( this . bitsPerChar != Math . log2 ( chars . length ) ) {
910 throw new Error ( 'EntropyString only supports CharSets with a power of 2 characters' )
1011 }
11- this . charsPerChunk = lcm ( this . bitsPerChar , 8 ) / this . bitsPerChar
12+ this . ndxFn = this . _ndxFn ( this . bitsPerChar )
13+ this . charsPerChunk = lcm ( this . bitsPerChar , bitsPerByte ) / this . bitsPerChar
1214 }
1315
1416 use ( chars ) {
@@ -28,63 +30,45 @@ class CharSet {
2830 }
2931 this . chars = chars
3032 }
31- }
32-
33- const _ndx64 = ( chunk , slice , bytes ) => {
34- return _ndxGen ( chunk , slice , bytes , 6 )
35- }
36-
37- const _ndx32 = ( chunk , slice , bytes ) => {
38- return _ndxGen ( chunk , slice , bytes , 5 )
39- }
4033
41- const _ndx16 = ( chunk , slice , bytes ) => {
42- return _ndxDiv ( chunk , slice , bytes , 4 )
43- }
44-
45- const _ndx8 = ( chunk , slice , bytes ) => {
46- return _ndxGen ( chunk , slice , bytes , 3 )
47- }
48-
49- const _ndx4 = ( chunk , slice , bytes ) => {
50- return _ndxDiv ( chunk , slice , bytes , 2 )
51- }
52-
53- const _ndx2 = ( chunk , slice , bytes ) => {
54- return _ndxDiv ( chunk , slice , bytes , 1 )
55- }
56-
57- const _ndxGen = ( chunk , slice , bytes , bitsPerChar ) => {
58- let bitsPerByte = 8
59- let slicesPerChunk = lcm ( bitsPerChar , bitsPerByte ) / bitsPerByte
60- let bNum = chunk * slicesPerChunk
34+ _ndxFn ( bitsPerChar ) {
35+ let bitsPerByte = 8
36+
37+ if ( lcm ( bitsPerChar , bitsPerByte ) === bitsPerByte ) {
38+ return function ( chunk , slice , bytes ) {
39+ let lShift = bitsPerChar
40+ let rShift = bitsPerByte - bitsPerChar
41+ return ( ( bytes [ chunk ] << ( lShift * slice ) ) & 0xff ) >> rShift
42+ }
43+ }
44+ else {
45+ return function ( chunk , slice , bytes ) {
46+ let slicesPerChunk = lcm ( bitsPerChar , bitsPerByte ) / bitsPerByte
47+ let bNum = chunk * slicesPerChunk
6148
62- let rShift = bitsPerByte - bitsPerChar
63- let lOffset = Math . floor ( ( slice * bitsPerChar ) / bitsPerByte )
64- let lShift = ( slice * bitsPerChar ) % bitsPerByte
49+ let rShift = bitsPerByte - bitsPerChar
50+ let lOffset = Math . floor ( ( slice * bitsPerChar ) / bitsPerByte )
51+ let lShift = ( slice * bitsPerChar ) % bitsPerByte
6552
66- let ndx = ( ( bytes [ bNum + lOffset ] << lShift ) & 0xff ) >> rShift
53+ let ndx = ( ( bytes [ bNum + lOffset ] << lShift ) & 0xff ) >> rShift
6754
68- let rOffset = Math . ceil ( ( slice * bitsPerChar ) / bitsPerByte )
69- let rShiftIt = ( ( rOffset + 1 ) * bitsPerByte - ( slice + 1 ) * bitsPerChar ) % bitsPerByte
70- if ( rShift < rShiftIt ) {
71- ndx += bytes [ bNum + rOffset ] >> rShiftIt
55+ let rOffset = Math . ceil ( ( slice * bitsPerChar ) / bitsPerByte )
56+ let rShiftIt = ( ( rOffset + 1 ) * bitsPerByte - ( slice + 1 ) * bitsPerChar ) % bitsPerByte
57+ if ( rShift < rShiftIt ) {
58+ ndx += bytes [ bNum + rOffset ] >> rShiftIt
59+ }
60+ return ndx
61+ }
62+ }
7263 }
73- return ndx
74- }
75-
76- const _ndxDiv = ( chunk , slice , bytes , bitsPerChar ) => {
77- let lShift = bitsPerChar
78- let rShift = 8 - bitsPerChar
79- return ( ( bytes [ chunk ] << ( lShift * slice ) ) & 0xff ) >> rShift
8064}
8165
8266export default {
83- charSet64 : new CharSet ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' , _ndx64 ) ,
84- charSet32 : new CharSet ( '2346789bdfghjmnpqrtBDFGHJLMNPQRT' , _ndx32 ) ,
85- charSet16 : new CharSet ( '0123456789abcdef' , _ndx16 ) ,
86- charSet8 : new CharSet ( '01234567' , _ndx8 ) ,
87- charSet4 : new CharSet ( 'ATCG' , _ndx4 ) ,
88- charSet2 : new CharSet ( '01' , _ndx2 ) ,
67+ charSet64 : new CharSet ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' ) ,
68+ charSet32 : new CharSet ( '2346789bdfghjmnpqrtBDFGHJLMNPQRT' ) ,
69+ charSet16 : new CharSet ( '0123456789abcdef' ) ,
70+ charSet8 : new CharSet ( '01234567' ) ,
71+ charSet4 : new CharSet ( 'ATCG' ) ,
72+ charSet2 : new CharSet ( '01' ) ,
8973 isValid : ( charSet ) => charSet instanceof CharSet
9074}
0 commit comments