Java的UUID.nameUUIDFromBytes用JavaScript编写?

时间:2017-11-27 07:17:13

标签: javascript

您好我有一个我无法控制的第三方应用程序,它使用Java的UUID.nameUUIDFromBytes来创建一个字符串。我需要重现用JS编写的这个函数。

OpenJDK's source我发现了这个:

public static UUID nameUUIDFromBytes(byte[] name) {
    MessageDigest md;
    try {
        md = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException nsae) {
        throw new InternalError("MD5 not supported", nsae);
    }
    byte[] md5Bytes = md.digest(name);
    md5Bytes[6]  &= 0x0f;  /* clear version        */
    md5Bytes[6]  |= 0x30;  /* set to version 3     */
    md5Bytes[8]  &= 0x3f;  /* clear variant        */
    md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(md5Bytes);
}

对于我的生活,我无法弄清楚,主要是因为JS抽象字节的方式。

TL:DR我只需要一个js函数,它将产生与UUID.nameUUIDFromBytes((VARIABLE).getBytes(Charsets.UTF_8)).toString()

相同的字符串

3 个答案:

答案 0 :(得分:2)

好的,这不是纯粹的js,而是nodejs。

const crypto = require('crypto')
function javaHash(in) {
    let md5Bytes = crypto.createHash('md5').update(in).digest()
    md5Bytes[6]  &= 0x0f;  /* clear version        */
    md5Bytes[6]  |= 0x30;  /* set to version 3     */
    md5Bytes[8]  &= 0x3f;  /* clear variant        */
    md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
    return md5bytes.toString(16)
}

答案 1 :(得分:1)

此解决方案为我提供了确切的UUID

const crypto = require('crypto');
const hexToUuid = require('hex-to-uuid');

const javaHash = (input) => {
    var md5Bytes = crypto.createHash('md5').update(input).digest()
    md5Bytes[6] &= 0x0f;  / clear version        /
    md5Bytes[6] |= 0x30;  / set to version 3     /
    md5Bytes[8] &= 0x3f;  / clear variant        /
    md5Bytes[8] |= 0x80;  / set to IETF variant  /
    return hexToUuid(md5Bytes.toString('hex'))
}

console.log('javaHash', javaHash("HelloWorld"));
    // 68e109f0-f40c-372a-95e0-5cc22786f8e6

答案 2 :(得分:0)

这个答案试图对以前的答案进行如下改进

  • 它在输出中包含连字符,就像 Java
  • 不再依赖不再支持的额外外部库
const crypto = require('crypto');

function javaHash(input:string) {
  let md5Bytes = crypto.createHash('md5').update(input).digest();
  md5Bytes[6]  &= 0x0f;  /* clear version        */
  md5Bytes[6]  |= 0x30;  /* set to version 3     */
  md5Bytes[8]  &= 0x3f;  /* clear variant        */
  md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
  const hex = md5Bytes.toString('hex')
  const uuid = hex.replace(/(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/, "$1-$2-$3-$4-$5");
  return uuid;
}

它依赖于长度恰好为 128 位的 UUID 规范