最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Java's UUID.nameUUIDFromBytes to written in JavaScript? - Stack Overflow

programmeradmin6浏览0评论

I have a 3rd party application that I can't control that uses Java's UUID.nameUUIDFromBytes to create a string. I need to reproduce this function written in JS.

In OpenJDK's source I found this:

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);
}

For the life of me I can't figure it out, mostly because of how JS abstracts bytes.

TL;DR: I just need a js function that will produce the same string as UUID.nameUUIDFromBytes((VARIABLE).getBytes(Charsets.UTF_8)).toString().

I have a 3rd party application that I can't control that uses Java's UUID.nameUUIDFromBytes to create a string. I need to reproduce this function written in JS.

In OpenJDK's source I found this:

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);
}

For the life of me I can't figure it out, mostly because of how JS abstracts bytes.

TL;DR: I just need a js function that will produce the same string as UUID.nameUUIDFromBytes((VARIABLE).getBytes(Charsets.UTF_8)).toString().

Share Improve this question edited Nov 9, 2020 at 16:56 Elias Zamaria 101k34 gold badges121 silver badges152 bronze badges asked Nov 27, 2017 at 7:17 Kaiden PrinceKaiden Prince 2372 silver badges9 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Okay so, this is not pure-js, but it is nodejs.

const crypto = require('crypto');

function javaHash(input) {
    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  */
    return md5Bytes.toString('hex');
}

This solution gave me exact UUID for me

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

This answer attempts to improve on the previous ones as follows

  • It includes the hyphens in the output, just like Java
  • Does not rely on additional external libraries that are not supported anymore
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;
}

It relies on the UUID spec being exactly 128bits in length

发布评论

评论列表(0)

  1. 暂无评论