Thông báo Digest (hàm băm) là byte [] in byte [] out
Một thông báo thông báo được định nghĩa là một hàm lấy một mảng byte thô và trả về một mảng byte thô (aka byte[]
). Ví dụ: SHA-1 (Thuật toán băm bảo mật 1) có kích thước phân loại là 160 bit hoặc 20 byte. Mảng byte thô thường không thể được hiểu là mã hóa ký tự như UTF-8 , bởi vì không phải mọi byte trong mỗi đơn hàng đều là mã hóa hợp pháp. Vì vậy, chuyển đổi chúng thành một String
với:
new String(md.digest(subject), StandardCharsets.UTF_8)
có thể tạo một số chuỗi bất hợp pháp hoặc có các con trỏ mã để ánh xạ Unicode không xác định :
[�a�ɹ??�%l�3~��.
Mã hóa nhị phân thành văn bản
Đối với mã hóa nhị phân thành văn bản được sử dụng. Với băm, cái được sử dụng nhiều nhất là mã hóa HEX hoặc Base16 . Về cơ bản một byte có thể có giá trị từ 0
đến 255
(hoặc -128
để 127
ký) tương đương với các đại diện HEX của 0x00
- 0xFF
. Do đó hex sẽ tăng gấp đôi độ dài cần thiết của đầu ra, điều đó có nghĩa là đầu ra 20 byte sẽ tạo ra chuỗi hex dài 40 ký tự, ví dụ:
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
Lưu ý rằng không bắt buộc phải sử dụng mã hóa hex. Bạn cũng có thể sử dụng một cái gì đó như base64 . Hex thường được ưa thích vì con người dễ đọc hơn và có độ dài đầu ra xác định mà không cần đệm.
Bạn có thể chuyển đổi một mảng byte thành hex chỉ với chức năng JDK:
new BigInteger(1, token).toString(16)
Tuy nhiên, lưu ý rằng BigInteger
sẽ diễn giải mảng byte đã cho dưới dạng số và không phải là chuỗi byte. Điều đó có nghĩa là các số 0 đứng đầu sẽ không được xuất ra và chuỗi kết quả có thể ngắn hơn 40 ký tự.
Sử dụng Thư viện để Mã hóa cho HEX
Bây giờ bạn có thể sao chép và dán một phương thức byte-hex chưa được kiểm tra từ Stack Overflow hoặc sử dụng các phụ thuộc lớn như Guava .
Để có giải pháp xử lý cho hầu hết các vấn đề liên quan đến byte, tôi đã triển khai một tiện ích để xử lý các trường hợp sau: byte-java (Github)
Để chuyển đổi mảng byte thông báo của bạn, bạn chỉ cần làm
String hex = Bytes.wrap(md.digest(subject)).encodeHex();
hoặc bạn chỉ có thể sử dụng tính năng băm tích hợp
String hex = Bytes.from(subject).hashSha1().encodeHex();
SHA1
không có dấu gạch nối, không biết điều đó sẽ tạo ra sự khác biệt.