M
Mike Schilling
Daniel O'Connell said:Mike Schilling said:Daniel O'Connell said:When I do this in Java, the output looks like:
2CFFFF1E-0CB4-11D9-A4BE-C3134102AA77
2CFFFF1F-0CB4-11D9-A4BE-C3134102AA77
2CFFFF20-0CB4-11D9-A4BE-C3134102AA77
2CFFFF21-0CB4-11D9-A4BE-C3134102AA77
2CFFFF22-0CB4-11D9-A4BE-C3134102AA77
2CFFFF23-0CB4-11D9-A4BE-C3134102AA77
2CFFFF24-0CB4-11D9-A4BE-C3134102AA77
2CFFFF25-0CB4-11D9-A4BE-C3134102AA77
2CFFFF26-0CB4-11D9-A4BE-C3134102AA77
2CFFFF27-0CB4-11D9-A4BE-C3134102AA77
2CFFFF28-0CB4-11D9-A4BE-C3134102AA77
2CFFFF29-0CB4-11D9-A4BE-C3134102AA77
C# output will be different from Java (due to the random numbers), but
if you run them at more or less the same time,
all UUIDs should be unique. The difference will be an increment in
the first group
the first, time-based, group should be larger for whichever is run
second
the second and third, also time-based, groups, should be identical
the last group should still end in AA77
My results:
D556A42D-0CA5-11D9-8D09-00000000AA77
D556A42E-0CA5-11D9-8D09-00000000AA77
D556A42F-0CA5-11D9-8D09-00000000AA77
D556A430-0CA5-11D9-8D09-00000000AA77
D556A431-0CA5-11D9-8D09-00000000AA77
D556A432-0CA5-11D9-8D09-00000000AA77
D556A433-0CA5-11D9-8D09-00000000AA77
D556A434-0CA5-11D9-8D09-00000000AA77
D556A435-0CA5-11D9-8D09-00000000AA77
D556A436-0CA5-11D9-8D09-00000000AA77
D556A437-0CA5-11D9-8D09-00000000AA77
D556A438-0CA5-11D9-8D09-00000000AA77
The straight 0's at the end seems a little odd, but that may just be an
aspect of my partiuclar machine.
It's definitely a bug. It appears to be in the translation of:
/** randomly generate a node ID. make the last two bytes
* 0xAA77, which cannot conflict with a real Ethernet address */
private void initializeNodeId()
{
byte barr[] = new byte[2];
Random r1 = new Random();
Random r2 = new Random(r1.hashCode());
r1.nextBytes(barr);
nodeId[0] = barr[0];
nodeId[1] = barr[1];
r2.nextBytes(barr);
nodeId[2] = barr[0];
nodeId[3] = barr[1];
nodeId[4] = (byte)0xaa;
nodeId[5] = 0x77;
}
I'll hazard a guess: that the nextBytes call translates to
System.Random.NextBytes(), which fills an array of *unsigned* bytes, and
that the results don't get copied back to barr, which is an array of
*signed* bytes. If so, it's the same bug I saw in 2002.
That does appear to be the case, and, frankly, I would be surprised if any
translator got this right. It seems like something only a person who knew
what the code was supposed to be doing could do.
I disagree. The translator knows enough to convert
Java.Util.Random.nextBytes(byte[]) to System.Random.NextBytes(byte[]); it
should also know the semantics of the call, i.e. that the call changes the
byte array. Even without that detailed knowledge, the default behavior
should be something like:
byte tempArr = new byte[barr.Length];
CopyToByteArray(barr, tempArr);
System.Random.NextBytes(tempArr);
CopyFromByteArray(tempArr, barr);
At any rate, the fact that JLCA silently produces errors like this is reason
enough for me not to use it.