Trong hướng dẫn này, chúng ta sẽ xem xét các cách khác nhau để chuyển đổi một mảng byte thành Chuỗi thập lục phân và ngược lại
Chúng tôi cũng sẽ hiểu cơ chế chuyển đổi và viết triển khai của chúng tôi để đạt được điều này
2. Chuyển đổi giữa byte và thập lục phân
Trước hết, chúng ta hãy xem logic chuyển đổi giữa số byte và số thập lục phân
2. 1. Byte sang thập lục phân
Các byte là số nguyên có chữ ký 8 bit trong Java. Do đó, chúng ta cần chuyển đổi từng phân đoạn 4 bit thành hex riêng biệt và nối chúng lại. Do đó, chúng tôi sẽ nhận được hai ký tự thập lục phân sau khi chuyển đổi
Chẳng hạn, chúng ta có thể viết 45 thành 0010 1101 ở dạng nhị phân và số thập lục phân tương đương sẽ là “2d”
0010 = 2 [base 10] = 2 [base 16]
1101 = 13 [base 10] = d [base 16]
Therefore: 45 = 0010 1101 = 0x2d
Hãy triển khai logic đơn giản này trong Java
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
Bây giờ, hãy hiểu đoạn mã trên bằng cách phân tích từng hoạt động. Trước hết, chúng tôi đã tạo một mảng char có độ dài 2 để lưu trữ đầu ra
char[] hexDigits = new char[2];
Tiếp theo, chúng tôi đã tách các bit bậc cao hơn bằng cách dịch phải 4 bit. Và sau đó, chúng tôi đã áp dụng mặt nạ để cô lập 4 bit bậc thấp hơn. Mặt nạ là bắt buộc vì các số âm được biểu diễn bên trong dưới dạng phần bù hai của số dương
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
Sau đó, chúng tôi chuyển đổi 4 bit còn lại thành thập lục phân
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
Cuối cùng, chúng ta tạo một đối tượng String từ mảng char. Và sau đó, trả về đối tượng này dưới dạng mảng thập lục phân đã chuyển đổi
Bây giờ, hãy cho chúng tôi hiểu cách tính năng này sẽ hoạt động đối với byte âm -4
hexDigits[0]:
1111 1100 >> 4 = 1111 1111 1111 1111 1111 1111 1111 1111
1111 1111 1111 1111 1111 1111 1111 1111 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1111 = 0xf
hexDigits[1]:
1111 1100 & 0xF = 0000 1100 = 0xc
Therefore: -4 [base 10] = 1111 1100 [base 2] = fc [base 16]
Cũng cần lưu ý rằng Nhân vật. Phương thức forDigit[] luôn trả về các ký tự chữ thường
2. 2. Thập lục phân thành Byte
Bây giờ, hãy chuyển đổi một chữ số thập lục phân thành byte. Như chúng ta đã biết, một byte chứa 8 bit. Do đó, chúng ta cần hai chữ số thập lục phân để tạo một byte
Trước hết, chúng tôi sẽ chuyển đổi từng chữ số thập lục phân thành nhị phân tương đương một cách riêng biệt
Và sau đó, chúng ta cần nối hai đoạn bốn bit để có được byte tương đương
Hexadecimal: 2d
2 = 0010 [base 2]
d = 1101 [base 2]
Therefore: 2d = 0010 1101 [base 2] = 45
Bây giờ, hãy viết thao tác trong Java
public byte hexToByte[String hexString] {
int firstDigit = toDigit[hexString.charAt[0]];
int secondDigit = toDigit[hexString.charAt[1]];
return [byte] [[firstDigit 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
0Như chúng ta đã biết, đầu ra sẽ luôn ở dạng chữ thường
3. 2. Chuỗi thập lục phân thành mảng byte
Trước hết, chúng ta cần kiểm tra xem độ dài của Chuỗi thập lục phân có phải là số chẵn không. Điều này là do Chuỗi thập lục phân có độ dài lẻ sẽ dẫn đến biểu diễn byte không chính xác
Bây giờ, chúng ta sẽ lặp qua mảng và chuyển đổi từng cặp thập lục phân thành một byte
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
14. Sử dụng Lớp BigInteger
Chúng ta có thể tạo một đối tượng kiểu BigInteger bằng cách chuyển một mảng signum và byte
Giờ đây, chúng ta có thể tạo Chuỗi thập lục phân với sự trợ giúp của định dạng phương thức tĩnh được xác định trong lớp Chuỗi
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
2Định dạng được cung cấp sẽ tạo một Chuỗi thập lục phân chữ thường có đệm bằng 0. Chúng tôi cũng có thể tạo một chuỗi chữ hoa bằng cách thay thế “x” bằng “X”
Ngoài ra, chúng ta có thể sử dụng phương thức toString[] từ BigInteger. Sự khác biệt tinh tế khi sử dụng phương thức toString[] là đầu ra không được đệm bằng các số 0 ở đầu
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
3Bây giờ, chúng ta hãy xem chuyển đổi Chuỗi thập lục phân thành Mảng byte
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
4Phương thức toByteArray[] tạo ra một bit dấu bổ sung. Chúng tôi đã viết mã cụ thể để xử lý bit bổ sung này
Do đó, chúng ta nên biết những chi tiết này trước khi sử dụng lớp BigInteger để chuyển đổi
5. Sử dụng Lớp DataTypeConverter
Lớp DataTypeConverter được cung cấp cùng với thư viện JAXB. Đây là một phần của thư viện chuẩn cho đến Java 8. Bắt đầu từ Java 9, chúng ta cần thêm java. xml. liên kết mô-đun với thời gian chạy một cách rõ ràng
Hãy xem triển khai bằng cách sử dụng lớp DataTypeConverter
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
5Như đã trình bày ở trên, sẽ rất thuận tiện khi sử dụng lớp DataTypeConverter. Đầu ra của phương thức printHexBinary[] luôn ở dạng chữ hoa. Lớp này cung cấp một tập hợp các phương thức in và phân tích cú pháp để chuyển đổi kiểu dữ liệu
Trước khi chọn phương pháp này, chúng ta cần đảm bảo rằng lớp sẽ có sẵn khi chạy
6. Sử dụng Thư viện Commons-Codec của Apache
Chúng tôi có thể sử dụng lớp Hex được cung cấp cùng với thư viện Apache commons-codec
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
6Đầu ra của encodeHexString luôn ở dạng chữ thường
7. Sử dụng Thư viện Guava của Google
Chúng ta hãy xem cách lớp BaseEncoding có thể được sử dụng để mã hóa và giải mã mảng byte thành Chuỗi thập lục phân
public String byteToHex[byte num] {
char[] hexDigits = new char[2];
hexDigits[0] = Character.forDigit[[num >> 4] & 0xF, 16];
hexDigits[1] = Character.forDigit[[num & 0xF], 16];
return new String[hexDigits];
}
7Theo mặc định, BaseEncoding mã hóa và giải mã bằng các ký tự viết hoa. Nếu chúng ta cần sử dụng các ký tự chữ thường, một phiên bản mã hóa mới sẽ được tạo bằng phương thức tĩnh
8. Sự kết luận
Trong bài viết này, chúng ta đã tìm hiểu thuật toán chuyển đổi giữa mảng byte sang Chuỗi thập lục phân. Chúng ta cũng đã thảo luận về các phương pháp khác nhau để mã hóa mảng byte thành chuỗi hex và ngược lại
Không nên thêm thư viện để chỉ sử dụng một vài phương thức tiện ích. Do đó, nếu chúng tôi chưa sử dụng các thư viện bên ngoài, chúng tôi nên sử dụng thuật toán đã thảo luận. Lớp DataTypeConverter là một cách khác để mã hóa/giải mã giữa các loại dữ liệu khác nhau