import static org.junit.Assert.*; import org.junit.Test; public class StringToolsTest { static final char [] data = {0xca, 0xfe, 0xeb, 0xab, 0xee}; static final String string5 = String.valueOf(data); static final String string0 = ""; static final String string1 = "a"; static final String string9 = "987654321"; @Test public void testFillBackwards() { long l = 0; assertEquals(0xcafeebabeeL, StringTools.fillBackwards(string5, l)); assertEquals(0L, StringTools.fillBackwards(string0, l)); assertEquals(0x61L, StringTools.fillBackwards(string1, l)); assertEquals(0x3837363534333231L, StringTools.fillBackwards(string9, l)); } } public class StringTools { public static long fillBackwards(String s, long d) { long result = 0L; byte[] bytes = s.getBytes(); for (int i=0; i<Math.min(8,bytes.length); i++){ result |= ((bytes[bytes.length-i-1] & 0xff) << (8*i)); } return result; } }
Solution bellow (highlight to show):
The problem is on the line 29 in "& 0xFF". I should be doing &0xFFL instead. Why ? bytes[x]&0xff is by default int (both operands are widened to int), but then << is applied, result of which is type of left operand (java spec) and this is |= to long result. Solution is to make & operator to work on long values by adding L to 0xFF.
Puzzler on snipplr.