Java Arrays.compareUnsigned: เรียง byte array แบบข้อมูลไบนารี ไม่ใช่เลขติดลบ
Java เก็บ byte เป็น signed ช่วงลบถึงบวก แต่ข้อมูล network, digest และ binary key มักตีความแต่ละ byte เป็น 0–255 ครับ Arrays.compareUnsigned เปรียบเทียบแบบ lexicographic โดยใช้ค่าที่ไม่ติดลบ
WHY: byte เดียวกันมีสองความหมาย
บิตทุกบิตเหมือนเดิม แต่ (byte) 0xFF มีค่า -1 ใน Java หากเปรียบเทียบ signed มันจะน้อยกว่า 0x01 ทั้งที่ protocol มองเป็น 255 ซึ่งมากกว่า 1 เหมือนป้ายราคาที่เครื่องหนึ่งอ่านเป็นหนี้ อีกเครื่องอ่านเป็นมูลค่าสูงสุด ต้องตกลง semantics ก่อนเรียง
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
byte[] high = {(byte) 0xFF};
byte[] low = {0x01};
assert Arrays.compare(high, low) < 0;
assert Arrays.compareUnsigned(high, low) > 0;
assert Arrays.compareUnsigned(
new byte[] {0x01, 0x02},
new byte[] {0x01, 0x03}
) < 0;
assert Arrays.compareUnsigned(
new byte[] {0x01},
new byte[] {0x01, 0x00}
) < 0;
System.out.println("unsigned comparison checks passed");
}
}
เมธอดหยุดที่ byte แรกที่ต่าง ถ้า prefix เท่ากัน array ที่สั้นกว่าจะมาก่อน นี่เหมาะกับ binary identifiers ที่กำหนด order แบบ unsigned แต่ไม่ควรใช้แทน constant-time comparison สำหรับ secret เพราะเวลาทำงานอาจเผยตำแหน่งแรกที่ต่าง
Recap
- เลือก signed หรือ unsigned ตาม protocol ไม่ใช่ตามความเคยชิน
-
compareUnsignedเรียงแบบ lexicographic - prefix เท่ากัน array สั้นมาก่อน
- secret ใช้ primitive ที่ออกแบบเพื่อลด timing side-channel