uuid v5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! https://psn.hatenablog.jp/entry/2018/05/28/235801 */ | |
export const generateUUIDv5 = (namespace, data) => { | |
const parseUUID = (namespace) => { | |
namespace = namespace.replaceAll('-', ''); | |
const output = new Uint8Array(Math.ceil(namespace.length / 2)); // 16 octets | |
for (let i = 0, pointer = 0; i < output.length; i++) { | |
output.set([parseInt(namespace.substring(pointer, pointer + 2), 16)], i); | |
pointer += 2; | |
} | |
return output; | |
}; | |
const formatUUID = (hash) => { | |
const chars = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.split(''); | |
const hashView = new Uint8Array(hash); | |
hashView[6] = (hashView[6] & 0x0f) | 0x50; // version(5) : [6]=xxxx yyyy => 0101 yyyy | |
hashView[8] = (hashView[8] & 0x3f) | 0x80; // variant(8) : [8]=xxxx yyyy => 10xx yyyy | |
const hashArray = Array.from(hashView).map(b => b.toString(16).padStart(2, '0')).join('').split(''); | |
for (let i = 0, p = 0; i < chars.length; i++) { | |
if (chars[i] === 'x') { | |
chars[i] = hashArray[p]; | |
p++; | |
} | |
} | |
return chars.join(''); | |
}; | |
const nsUint8 = parseUUID(namespace); | |
const dataUint8 = new TextEncoder().encode(data); | |
const digestData = new Uint8Array(nsUint8.length + dataUint8.length); | |
digestData.set(nsUint8); | |
digestData.set(dataUint8, nsUint8.length); | |
return crypto.subtle.digest('SHA-1', digestData).then(hash => { | |
return formatUUID(hash); | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment