@@ -4,12 +4,31 @@ var sha1 = require('js-sha1');
44/** List of hex digit for fast accessing by index */
55var HEX_DIGITS = '0123456789abcdef' . split ( '' ) ;
66
7+ /** Length of string containing uuid */
8+ var UUID_LENGTH = 36 ;
9+
10+ /** Regular expression for uuid testing */
11+ var UUID_REGEXP = / ^ [ 0 - 9 a - f ] { 8 } - [ 0 - 9 a - f ] { 4 } - [ 0 - 5 ] [ 0 - 9 a - f ] { 3 } - [ 0 8 9 a b ] [ 0 - 9 a - f ] { 3 } - [ 0 - 9 a - f ] { 12 } $ / i;
12+
13+ /** Map matching of hex number and corresponding byte */
14+ var HEX_TO_BYTE_MAP = ( function ( ) {
15+ var map = { } ;
16+
17+ for ( var i = 0 ; i < 256 ; i ++ ) {
18+ var hex = i . toString ( 16 ) ;
19+
20+ map [ hex . length === 1 ? '0' + hex : hex ] = i ;
21+ }
22+
23+ return map ;
24+ } ) ( ) ;
25+
726/**
827 * Converts unsigned byte to hex representation
928 * @param {number } ubyte The unsigned byte to convert
1029 * @returns {string } The hex representation
1130 */
12- var uint8ToHex = function ( ubyte ) {
31+ var uint8ToHex = function ( ubyte ) {
1332 var first = ubyte >> 4 ;
1433 var second = ubyte - ( first << 4 ) ;
1534
@@ -21,26 +40,27 @@ var uint8ToHex = function(ubyte) {
2140 * @param {Uint8Array } buf The unsigned bytes buffer
2241 * @returns {string } The hex string representation
2342 */
24- var uint8ArrayToHex = function ( buf ) {
25- var out = [ ] ;
43+ var uint8ArrayToHex = function ( buf ) {
44+ var out = '' ;
2645
2746 for ( var i = 0 ; i < buf . length ; i ++ ) {
28- out . push ( uint8ToHex ( buf [ i ] ) ) ;
47+ out += uint8ToHex ( buf [ i ] ) ;
2948 }
3049
31- return out . join ( '' ) ;
50+ return out ;
3251} ;
3352
3453/**
3554 * Converts string to buffer of char codes
3655 * @param {string } str The string to parse
3756 * @returns {Uint8Array } Buffer of char codes
3857 */
39- var stringToCharBuffer = function ( str ) {
40- var buffer = new Uint8Array ( str . length ) ;
58+ var stringToCharBuffer = function ( str ) {
59+ var escapedStr = unescape ( encodeURIComponent ( str ) ) ;
60+ var buffer = new Uint8Array ( escapedStr . length ) ;
4161
42- for ( var i = 0 ; i < str . length ; i ++ ) {
43- buffer [ i ] = str [ i ] . charCodeAt ( 0 ) ;
62+ for ( var i = 0 ; i < escapedStr . length ; i ++ ) {
63+ buffer [ i ] = escapedStr [ i ] . charCodeAt ( 0 ) ;
4464 }
4565
4666 return buffer ;
@@ -51,7 +71,7 @@ var stringToCharBuffer = function(str) {
5171 * @param {Uint8Array } buf Buffer of char codes
5272 * @returns {Uint8Array } MD5 hash buffer
5373 */
54- var md5Hash = function ( buf ) {
74+ var md5Hash = function ( buf ) {
5575 return new Uint8Array ( md5 . arrayBuffer ( buf ) ) ;
5676} ;
5777
@@ -60,7 +80,7 @@ var md5Hash = function(buf) {
6080 * @param {Uint8Array } buf Buffer of char codes
6181 * @returns {Uint8Array } SHA-1 hash buffer
6282 */
63- var sha1Hash = function ( buf ) {
83+ var sha1Hash = function ( buf ) {
6484 return new Uint8Array ( sha1 . arrayBuffer ( buf ) ) ;
6585} ;
6686
@@ -70,7 +90,7 @@ var sha1Hash = function(buf) {
7090 * @param {Uint8Array } buf2 The second buffer to concatenate
7191 * @returns {Uint8Array } Concatenation result
7292 */
73- var concatBuffers = function ( buf1 , buf2 ) {
93+ var concatBuffers = function ( buf1 , buf2 ) {
7494 var out = new Uint8Array ( buf1 . length + buf2 . length ) ;
7595
7696 out . set ( new Uint8Array ( buf1 ) , 0 ) ;
@@ -79,44 +99,81 @@ var concatBuffers = function(buf1, buf2) {
7999 return out ;
80100} ;
81101
102+ /**
103+ * Validates UUID
104+ * @param {string } uuid UUID to validate
105+ * @return {boolean } Validation result
106+ */
107+ var validateUuid = function ( uuid ) {
108+ return typeof uuid === 'string' && uuid . length === UUID_LENGTH && UUID_REGEXP . test ( uuid ) ;
109+ } ;
110+
111+ /**
112+ * Parses UUID into a buffer
113+ * @param {string } uuid UUID to parse
114+ * @returns {Uint8Array } Ready buffer
115+ */
116+ var parseUuid = function ( uuid ) {
117+ if ( ! validateUuid ( uuid ) ) {
118+ throw TypeError ( 'Invalid UUID' ) ;
119+ }
120+
121+ var buf = new Uint8Array ( 16 ) ;
122+ var strIndex = 0 ;
123+ var bufIndex = 0 ;
124+
125+ while ( strIndex < uuid . length ) {
126+ if ( uuid [ strIndex ] === '-' ) {
127+ strIndex ++ ;
128+ continue ;
129+ }
130+
131+ var oct = ( uuid [ strIndex ] + uuid [ strIndex + 1 ] ) . toLowerCase ( ) ;
132+ buf [ bufIndex ] = HEX_TO_BYTE_MAP [ oct ] ;
133+
134+ bufIndex ++ ;
135+ strIndex += 2 ;
136+ }
137+
138+ return buf ;
139+ } ;
140+
82141/**
83142 * Creates uuid from hash buffer
84143 * @param {Uint8Array } hashBuffer Hash buffer
85144 * @param {3|5 } version Version of uuid
86145 * @returns {string } The uuid
87146 */
88- var hashToUuid = function ( hashBuffer , version ) {
89- return [
147+ var hashToUuid = function ( hashBuffer , version ) {
148+ return (
90149 // The low field of the timestamp
91- uint8ArrayToHex ( hashBuffer . slice ( 0 , 4 ) ) ,
92- '-' ,
93-
150+ uint8ArrayToHex ( hashBuffer . slice ( 0 , 4 ) ) +
151+ '-' +
94152 // The middle field of the timestamp
95- uint8ArrayToHex ( hashBuffer . slice ( 4 , 6 ) ) ,
96- '-' ,
97-
153+ uint8ArrayToHex ( hashBuffer . slice ( 4 , 6 ) ) +
154+ '-' +
98155 // The high field of the timestamp multiplexed with the version number
99- uint8ToHex ( ( hashBuffer [ 6 ] & 0x0f ) | parseInt ( version * 10 , 16 ) ) ,
100- uint8ToHex ( hashBuffer [ 7 ] ) ,
101- '-' ,
102-
156+ uint8ToHex ( ( hashBuffer [ 6 ] & 0x0f ) | parseInt ( version * 10 , 16 ) ) +
157+ uint8ToHex ( hashBuffer [ 7 ] ) +
158+ '-' +
103159 // The high field of the clock sequence multiplexed with the variant
104- uint8ToHex ( ( hashBuffer [ 8 ] & 0x3f ) | 0x80 ) ,
160+ uint8ToHex ( ( hashBuffer [ 8 ] & 0x3f ) | 0x80 ) +
105161 // The low field of the clock sequence
106- uint8ToHex ( hashBuffer [ 9 ] ) ,
107- '-' ,
162+ uint8ToHex ( hashBuffer [ 9 ] ) +
163+ '-' +
108164 // The spatially unique node identifier
109-
110165 uint8ArrayToHex ( hashBuffer . slice ( 10 , 16 ) )
111- ] . join ( '' ) ;
166+ ) ;
112167} ;
113168
114169module . exports = {
115- uint8ToHex,
116- uint8ArrayToHex,
117- stringToCharBuffer,
118- md5Hash,
119- sha1Hash,
120- concatBuffers,
121- hashToUuid
170+ uint8ToHex : uint8ToHex ,
171+ uint8ArrayToHex : uint8ArrayToHex ,
172+ stringToCharBuffer : stringToCharBuffer ,
173+ md5Hash : md5Hash ,
174+ sha1Hash : sha1Hash ,
175+ concatBuffers : concatBuffers ,
176+ validateUuid : validateUuid ,
177+ parseUuid : parseUuid ,
178+ hashToUuid : hashToUuid ,
122179} ;
0 commit comments