1

I am trying to create a deterministic UUID in java to generate same UUID as we have in our ruby codebase but unable to do so and need help.

#ruby code using uuidtools gem (version: 2.1.5)
# UUIDTools::UUID_OID_NAMESPACE is UUID created for string "6ba7b812-9dad-11d1-80b4-00c04fd430c8".
# github link for gem: https://github.com/sporkmonger/uuidtools
UUIDTools::UUID.md5_create(UUIDTools::UUID_OID_NAMESPACE, "tej").to_s
## OUTPUT: d7d1d470-3585-589e-cf25-d2bcb54c7ba2


// java code using NameBasedGenerator from java-uuid-generator-3.1.4.
MessageDigest md = MessageDigest.getInstance("MD5");
NameBasedGenerator nameBasedGenerator = new NameBasedGenerator(NameBasedGenerator.NAMESPACE_OID, md, UUIDType.NAME_BASED_MD5);
nameBasedGenerator.generate("tej").toString();
// OUTPUT: d7d1d470-3585-389e-8f25-d2bcb54c7ba2

// java code using uuid-creator-4.6.1
UUID uuid = UuidCreator.getNameBasedMd5(UuidNamespace.NAMESPACE_ISO_OID, "tej");
uuid.toString();
// OUTPUT: d7d1d470-3585-389e-8f25-d2bcb54c7ba2

I tried with couple of other strings as well and every time first character of either 3rd or 4th part (or both) of the output is different in java and ruby. Is there any issue in any of these libs (suspecting it to be in ruby) or am I doing something wrong, I mean should I change version of java lib I am using (can't make any change in ruby and also with java it will be difficult to downgrade as this lib would already be imported as part of jackson but i guess upgrade should not be an issue, hopefully).

Have referred above suggestions from: What namespace does the JDK use to generate a UUID with nameUUIDFromBytes?

What I saw as difference in the UUIDs generated using ruby and java libs was that the variant output was different for the two. But that looks to be more of the implementation of variant method in the two libs/languages (in ruby we are returning 4 when the variant is 2, I assume this wouldn't have impact on the UUID generation part). Please find the implementation of variant method below:

###RUBY
##
# Returns the UUID variant.
# Possible values:
# 0b000 - Reserved, NCS backward compatibility.
# 0b100 - The variant specified in this document.
# 0b110 - Reserved, Microsoft Corporation backward compatibility.
# 0b111 - Reserved for future definition.
def variant
  variant_raw = (clock_seq_hi_and_reserved >> 5)
  result = nil
  if (variant_raw >> 2) == 0
    result = 0x000
  elsif (variant_raw >> 1) == 2
    result = 0x100
  else
    result = variant_raw
  end
  return (result >> 6)
end

//JAVA:
/**
 * The variant number associated with this {@code UUID}.  The variant
 * number describes the layout of the {@code UUID}.
 *
 * The variant number has the following meaning:
 * <ul>
 * <li>0    Reserved for NCS backward compatibility
 * <li>2    <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>
 * (Leach-Salz), used by this class
 * <li>6    Reserved, Microsoft Corporation backward compatibility
 * <li>7    Reserved for future definition
 * </ul>
 *
 * @return  The variant number of this {@code UUID}
 */
public int variant() {
    // This field is composed of a varying number of bits.
    // 0    -    -    Reserved for NCS backward compatibility
    // 1    0    -    The IETF aka Leach-Salz variant (used by this class)
    // 1    1    0    Reserved, Microsoft backward compatibility
    // 1    1    1    Reserved for future definition.
    return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))
                  & (leastSigBits >> 63));
}

1 Answers1

0

On Linux, uuidgen generates the same UUID as the Java libraries generate:

$ uuidgen --namespace @oid --md5 --name "tej"
d7d1d470-3585-389e-8f25-d2bcb54c7ba2

Python also generates the same UUID:

>>> import uuid
>>> uuid.uuid3(uuid.NAMESPACE_OID, 'tej')
UUID('d7d1d470-3585-389e-8f25-d2bcb54c7ba2')

The same for Javascript:

> require('uuid').v3('tej', '6ba7b812-9dad-11d1-80b4-00c04fd430c8')
'd7d1d470-3585-389e-8f25-d2bcb54c7ba2'

You are not doing anything wrong. The ruby library used is returning wrong values. I think you should find another lib for ruby.

fabiolimace
  • 972
  • 11
  • 13