Could someone explain to me what the following Java code is doing?
byte s[] = getByteArray()
for(.....)
Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).subst开发者_Python百科ring(6);
I understand that you are trying to convert the byte into hex string. What I don't understand is how that is done. For instance if s[i] was 00000001 (decimal 1) than could you please explain:
- Why 0x000000ff & 00000001 ? Why not directly use 00000001?
- Why result from #1 | 0xffffff00?
- Finally why substring(6) is applied?
Thanks.
It's basically because bytes are signed in Java. If you promote a byte to an int, it will sign extend, meaning that the byte 0xf2
will become 0xfffffff2
. Sign extension is a method to keep the value the same when widening it, by copying the most significant (sign) bit into all the higher-order bits. Both those values above are -14
in two's complement notation. If instead you had widened 0xf2
to 0x000000f2
, it would be 242
, probably not what you want.
So the &
operation is to strip off any of those extended bits, leaving only the least significant 8 bits. However, since you're going to be forcing those bits to 1 in the next step anyway, this step seems a bit of a waste.
The |
operation following that will force all those upper bits to be 1 so that you're guaranteed to get an 8-character string from ffffff00
through ffffffff
inclusive (since toHexString
doesn't give you leading zeroes, it would translate 7
into "7"
rather than the "07"
that you want).
The substring(6)
is then applied so that you only get the last two of those eight hex digits.
It seems a very convoluted way of ensuring you get a two-character hex string to me when you can just use String.format ("%02x", s[i])
. However, it's possible that this particular snippet of code may predate Java 5 when String.format
was introduced.
If you run the following program:
public class testprog {
public static void compare (String s1, String s2) {
if (!s1.equals(s2))
System.out.println ("Different: " + s1 + " " + s2);
}
public static void main(String args[]) {
byte b = -128;
while (b < 127) {
compare (
Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
String.format("%02x", b, args));
b++;
}
compare (
Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
String.format("%02x", b, args));
System.out.println ("Done");
}
}
you'll see that the two expressions are identical - it just spits out Done
since the two expressions produce the same result in all cases.
精彩评论