Java에서 바이트 배열을 16 진수로 변환하는 방법은 무엇입니까?
16 진수로 많은 바이트 배열이 인쇄 할 수없는 요소가 많기 때문에 쉬운 방법으로 인쇄하는 무의미합니다. 내가 필요한 것은 다음과 같은 형식의 정확한 16 진수 코드입니다.3a5f771c
에서 토론 여기에 , 특히 이 대답이 내가 현재 사용하는 기능 현관은 다음과 같습니다
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
내 자신의 작은 벤치 마크 (천만 바이트, 256 바이트 1,000 만 번)는 다른 대안보다 훨씬 빠르다는 것을 보여줍니다. 이는 긴 어레이에서 약 절반의 시간입니다. 내가 회의 답변과 비교하여 비트 연산으로 전환하면 --- 토론에서 제안한대로 --- 긴 배열의 시간을 약 20 % 줄였습니다. (편집 : 대안 빠르다는 것은 토론에서 제공되는 대안 코드를 의미합니다. 성능은 매우 대안 코드를 사용하는 Commons 코덱과 동일합니다.)
아파치 코 몬즈 코덱 라이브러리는이 진수 작업의 바로 이런 종류의 작업을 수행하는 클래스입니다.
import org.apache.commons.codec.binary.Hex;
String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );
JAXB (Java Architecture for XML Binding) 의 일부인 메소드 는를javax.xml.bind.DatatypeConverter.printHexBinary()
byte[]
16 진 세련된 로 변환하는 편리한 방법 . 이 클래스에는 다른 많은 유용한 데이터 조작 방법도 포함되어 있습니다.DatatypeConverter
Java 8 및 이전 버전에서 JAXB는 Java 표준 라이브러리의 일부였습니다. 모든 Java EE 패키지를 자체 라이브러리로 이동하려는 노력의 일환으로 Java 9 에서 더 이상 사용하지 않고 Java 11에서 제거되었습니다 . 긴 이야기 입니다. 이제는 javax.xml.bind
존재하지 않는 것을 포함하는 JAXB를 사용 DatatypeConverter
하여 Maven에서 JAXB API 및 JAXB 실행 을 설치해야합니다 .
사용 예 :
byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);
결과 :
000086003D
이 답변과 같은 이 하나 .
가장 간단한 솔루션, 외부 라이브러리 없음, 숫자 상수 없음 :
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
완전성을위한 Guava 솔루션 :
import com.google.common.io.BaseEncoding;
...
byte[] bytes = "Hello world".getBytes(StandardCharsets.UTF_8);
final String hex = BaseEncoding.base16().lowerCase().encode(bytes);
이제 hex
입니다 "48656c6c6f20776f726c64"
.
이 간단한 하나의 라이너는 작동합니다
String result = new BigInteger(1, inputBytes).toString(16);
편집-이것을 사용하면 선행 0이 제거됩니다. 지적 해 주신 @Voicu에게 감사드립니다.
DataTypeConverter 클래스 사용javax.xml.bind.DataTypeConverter
String hexString = DatatypeConverter.printHexBinary(bytes[] raw);
해시와 같은 고정 길이에 대해 다음과 같이 사용합니다.
md5sum = String.format("%032x", new BigInteger(1, md.digest()));
여기에서 세 가지 방법을 찾았습니다. http://www.rgagnon.com/javadetails/java-0596.html
그가 또한 언급했듯이 가장 우아한 것은 다음과 같습니다.
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
룩업 테이블을 저장하는 약간의 비용으로 구현은 간단하고 매우 빠 사용합니다.
private static final char[] BYTE2HEX=(
"000102030405060708090A0B0C0D0E0F"+
"101112131415161718191A1B1C1D1E1F"+
"202122232425262728292A2B2C2D2E2F"+
"303132333435363738393A3B3C3D3E3F"+
"404142434445464748494A4B4C4D4E4F"+
"505152535455565758595A5B5C5D5E5F"+
"606162636465666768696A6B6C6D6E6F"+
"707172737475767778797A7B7C7D7E7F"+
"808182838485868788898A8B8C8D8E8F"+
"909192939495969798999A9B9C9D9E9F"+
"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"+
"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"+
"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"+
"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"+
"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"+
"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF").toCharArray();
;
public static String getHexString(byte[] bytes) {
final int len=bytes.length;
final char[] chars=new char[len<<1];
int hexIndex;
int idx=0;
int ofs=0;
while (ofs<len) {
hexIndex=(bytes[ofs++] & 0xFF)<<1;
chars[idx++]=BYTE2HEX[hexIndex++];
chars[idx++]=BYTE2HEX[hexIndex];
}
return new String(chars);
}
이 어떤가요?
String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
다음은 간단한 (한 줄짜리)에서 복잡한 (거대한 라이브러리)로 정렬 된 몇 가지 일반적인 옵션입니다.
옵션 1 : 코드 스 니펫-단순
매우 간단한 해결책 중 하나는 BigInteger
의 16 진수 표현 을 사용하는 것입니다 .
new BigInteger(1, someByteArray).toString(16)
이것은 임의의 바이트 문자열 이 아닌 숫자를 처리하기 때문에 선행 0을 생략합니다. 이것은 원하는 수도 있고 아닐 수도 있습니다 (예 : vs ). 이것은 또한 다음 옵션에 비해 약 50 배 느리게 매우 느립니다 .000AE3
0AE3
옵션 2 : 코드 스 니펫-고급
다음은 대문자 / 소문자 및 엔디안을 지원하는 완전한 기능의 코드 스 니펫 입니다. 모든 최신 Java 버전 (5+)과 호환되어야합니다.
private static final char[] LOOKUP_TABLE_LOWER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
private static final char[] LOOKUP_TABLE_UPPER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
public static String encode(byte[] byteArray, boolean upperCase, ByteOrder byteOrder) {
// our output size will be exactly 2x byte-array length
final char[] buffer = new char[byteArray.length * 2];
// choose lower or uppercase lookup table
final char[] lookup = upperCase ? LOOKUP_TABLE_UPPER : LOOKUP_TABLE_LOWER;
int index;
for (int i = 0; i < byteArray.length; i++) {
// for little endian we count from last to first
index = (byteOrder == ByteOrder.BIG_ENDIAN) ? i : byteArray.length - i - 1;
// extract the upper 4 bit and look up char (0-A)
buffer[i << 1] = lookup[(byteArray[index] >> 4) & 0xF];
// extract the lower 4 bit and look up char (0-A)
buffer[(i << 1) + 1] = lookup[(byteArray[index] & 0xF)];
}
return new String(buffer);
}
public static String encode(byte[] byteArray) {
return encode(byteArray, false, ByteOrder.BIG_ENDIAN);
}
이 옵션으로 3의 코드를 사용합니다. JMH 마이크로 벤치 마크 를보고 몇 가지 구현을 비교 하려면 여기를 참조하십시오 . Apache v2 비용 및 비용이 포함 된 전체 소스 코드는 여기 에서에서 수 있습니다 .
옵션 3 : 최적화 된 소규모 라이브러리 사용 : bytes-java
이전 프로젝트에서 작업하는 동안 Java에서 바이트를위한 작은 툴킷을 만들었습니다. 외부 사양이 Java 7 이상과 호환됩니다. 여기에는 매우 빠르고 잘 테스트 된 HEX / 비용이 포함됩니다.
import at.favre.lib.bytes.Bytes;
...
Bytes.wrap(someByteArray).encodeHex()
Github : bytes-java 에서 확인할 수 있습니다 .
옵션 4 : Apache Commons 코덱
물론 좋은 'ol commons 코덱이 있습니다. ( 경고 의견 ) 위에 설명 된 프로젝트에서 작업하는 동안 코드를 분석하고 매우 실망했습니다. 많은 구성되지 않은 코드, 쓸모없고 이국적인 코덱은 아마도 아주 소수이고 상당히 많이 엔지니어링되고 인기있는 코덱 (Base64)의 느린 구현에만 유용 할 것입니다. 나는 당신이 사용하는 것을 사용하거나 대안을 사용하고 따라서 사용하는 정보에 입각 한 결정을 내릴 것입니다. 어쨌든 여전히 사용하고 있고 여기에 코드 스 니펫이 있습니다.
import org.apache.commons.codec.binary.Hex;
...
Hex.encodeHexString(someByteArray));
옵션 5 : Google Guava
당신은 이미 구아바 를 의존성으로 가지고 있습니다. 다음을 사용하십시오.
import com.google.common.io.BaseEncoding;
...
BaseEncoding.base16().lowerCase().encode(someByteArray);
옵션 6 : 스프링 보안
Spring Security 와 함께 Spring 프레임 워크 를 사용하는 경우 다음을 사용할 수 있습니다.
import org.springframework.security.crypto.codec.Hex
...
Hex.encode(someByteArray);
Java 9 전화 또는 'JAXB 사용 안 함 javax / xml / bind / DatatypeConverter'
이전 Java (8 이하) 버전에서는 JAXB 용 Java 코드가 있음으로 포함되었습니다. Java 9 및 Jigsaw 모듈화 이후 코드는 모듈 외부의 다른 코드에 액세스 할 수 없습니다. 따라서 다음과 같은 예외가 발생하면 유의하십시오.
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Java 9 이상이 JVM에서 사용할 때. 구현을 위의 대안 중 하나로 전환하십시오. 이 질문을 참조하십시오 .
나는 이것을 사용하는 것을 선호합니다 :
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes, int offset, int count) {
char[] hexChars = new char[count * 2];
for ( int j = 0; j < count; j++ ) {
int v = bytes[j+offset] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
받아 들여지는 대답의 약간 더 유연한 적응입니다. 개인적으로 나는 더 많은 상황에서 사용할 수 있습니다.
나는 일반적으로 다음 방법을 사용하지만 최선의 방법인지 아닌지 모르겠습니다.
private static String digits = "0123456789abcdef";
public static String toHex(byte[] data){
StringBuffer buf = new StringBuffer();
for (int i = 0; i != data.length; i++)
{
int v = data[i] & 0xff;
buf.append(digits.charAt(v >> 4));
buf.append(digits.charAt(v & 0xf));
}
return buf.toString();
}
좋습니다. 이렇게하는 방법은 여러 가지의 경우 라이브러리를 사용하기로 결정한 새 라이브러리를 추가하기 전에 이미 프로젝트의 일부인 라이브러리에 작업이 구현 확인하기 위해 프로젝트를 살펴 보는 것이 좋습니다. 그냥 이렇게. 예를 들어 아직 가지고 있지 않은 경우
org.apache.commons.codec.binary.Hex
아마 당신은 ...
org.apache.xerces.impl.dv.util.HexBin
Spring Security 프레임 워크를 사용하는 경우 다음에서 사용할 수 있습니다.
import org.springframework.security.crypto.codec.Hex
final String testString = "Test String";
final byte[] byteArray = testString.getBytes();
System.out.println(Hex.encode(byteArray));
간단한 기능을 위해 유틸리티 병을 추가하는 것은 좋은 선택이 아닙니다. 대신 고유 한 유틸리티 클래스를 조합하십시오. 다음은 더 빠른 구현이 가능합니다.
public class ByteHex {
public static int hexToByte(char ch) {
if ('0' <= ch && ch <= '9') return ch - '0';
if ('A' <= ch && ch <= 'F') return ch - 'A' + 10;
if ('a' <= ch && ch <= 'f') return ch - 'a' + 10;
return -1;
}
private static final String[] byteToHexTable = new String[]
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
};
private static final String[] byteToHexTableLowerCase = new String[]
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"
};
public static String byteToHex(byte b){
return byteToHexTable[b & 0xFF];
}
public static String byteToHex(byte[] bytes){
if(bytes == null) return null;
StringBuilder sb = new StringBuilder(bytes.length*2);
for(byte b : bytes) sb.append(byteToHexTable[b & 0xFF]);
return sb.toString();
}
public static String byteToHex(short[] bytes){
StringBuilder sb = new StringBuilder(bytes.length*2);
for(short b : bytes) sb.append(byteToHexTable[((byte)b) & 0xFF]);
return sb.toString();
}
public static String byteToHexLowerCase(byte[] bytes){
StringBuilder sb = new StringBuilder(bytes.length*2);
for(byte b : bytes) sb.append(byteToHexTableLowerCase[b & 0xFF]);
return sb.toString();
}
public static byte[] hexToByte(String hexString) {
if(hexString == null) return null;
byte[] byteArray = new byte[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
byteArray[i / 2] = (byte) (hexToByte(hexString.charAt(i)) * 16 + hexToByte(hexString.charAt(i+1)));
}
return byteArray;
}
public static byte hexPairToByte(char ch1, char ch2) {
return (byte) (hexToByte(ch1) * 16 + hexToByte(ch2));
}
}
@maybewecouldstealavan이 제안한 솔루션의 작은 변형으로, 출력 16 진수 숫자에서 N 바이트를 수행으로 함께 묶을 수 있습니다.
final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
final static char BUNDLE_SEP = ' ';
public static String bytesToHexString(byte[] bytes, int bundleSize /*[bytes]*/]) {
char[] hexChars = new char[(bytes.length * 2) + (bytes.length / bundleSize)];
for (int j = 0, k = 1; j < bytes.length; j++, k++) {
int v = bytes[j] & 0xFF;
int start = (j * 2) + j/bundleSize;
hexChars[start] = HEX_ARRAY[v >>> 4];
hexChars[start + 1] = HEX_ARRAY[v & 0x0F];
if ((k % bundleSize) == 0) {
hexChars[start + 2] = BUNDLE_SEP;
}
}
return new String(hexChars).trim();
}
그건 :
bytesToHexString("..DOOM..".toCharArray().getBytes(), 2);
2E2E 444F 4F4D 2E2E
bytesToHexString("..DOOM..".toCharArray().getBytes(), 4);
2E2E444F 4F4D2E2E
이 페이지에서 해결되지 않는 솔루션을 없습니다.
- 루프 사용
- 잘 발생하는 발생하는 실행에 java.lang.NoClassDefFoundError를 발생시키는 javax.xml.bind.DatatypeConverter
(내가 다른 결함이없는 솔루션이 없습니다)
import java.math.BigInteger;
import static java.lang.System.out;
public final class App2 {
// | proposed solution.
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
final int evenLength = (int)(2 * Math.ceil(length / 2.0));
final String format = "%0" + evenLength + "x";
final String result = String.format (format, new BigInteger(bytes));
return result;
}
public static void main(String[] args) throws Exception {
// 00
out.println(encode(new byte[] {}));
// 01
out.println(encode(new byte[] {1}));
//203040
out.println(encode(new byte[] {0x20, 0x30, 0x40}));
// 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
out.println(encode("All your base are belong to us.".getBytes()));
}
}
62 개의 opcode에서 얻을 수 없었지만 첫 번째 바이트가 0x10보다 작은 경우 0 패딩없이 살 수있는 다음 솔루션은 23 개의 opcode 만 사용합니다. "문자열 길이가 홀수 인 경우 0으로 채움"과 같은 "자신을 구현하기 쉬운"솔루션이 기본 구현을 아직 사용할 수없는 경우 (또는 BigInteger에 0을 접두사로 사용하는 경우) 얼마나 많은 비용이 많이 많이 지 보여줍니다. toString).
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
return new BigInteger(bytes).toString(16);
}
내 솔루션은 maybeWeCouldStealAVan의 솔루션을 기반으로하지만 추가로 할당 된 조회 테이블에 의존하지 않습니다. 'int-to-char'캐스트 해킹을 사용하지 않습니다 (실제로 Character.forDigit()
는 숫자가 실제로 무엇인지 확인하기 비교를 수행합니다) 따라서 약간 느릴 수 있습니다. 원하는 곳에서 자유롭게 사용하십시오. 건배.
public static String bytesToHex(final byte[] bytes)
{
final int numBytes = bytes.length;
final char[] container = new char[numBytes * 2];
for (int i = 0; i < numBytes; i++)
{
final int b = bytes[i] & 0xFF;
container[i * 2] = Character.forDigit(b >>> 4, 0x10);
container[i * 2 + 1] = Character.forDigit(b & 0xF, 0x10);
}
return new String(container);
}
// 바이트 이동이 더 많이입니다. // 이것도 사용할 수 있습니다.
public static String getHexString (String s)
{
byte[] buf = s.getBytes();
StringBuffer sb = new StringBuffer();
for (byte b:buf)
{
sb.append(String.format("%x", b));
}
return sb.toString();
}
치환과 똑같은 바이트 배열을 보유하고 있습니다. Java 구현을 사용하여 변환했습니다.
class ByteArray:
@classmethod
def char(cls, args=[]):
cls.hexArray = "0123456789ABCDEF".encode('utf-16')
j = 0
length = (cls.hexArray)
if j < length:
v = j & 0xFF
hexChars = [None, None]
hexChars[j * 2] = str( cls.hexArray) + str(v)
hexChars[j * 2 + 1] = str(cls.hexArray) + str(v) + str(0x0F)
# Use if you want...
#hexChars.pop()
return str(hexChars)
array = ByteArray()
print array.char(args=[])
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
여기에 java.util.Base64
구현 구현 (부분)이 있습니다. 예쁘지 보편적 보상?
public class Base16/*a.k.a. Hex*/ {
public static class Encoder{
private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
private boolean upper;
public Encoder(boolean upper) {
this.upper=upper;
}
public String encode(byte[] data){
char[] value=new char[data.length*2];
char[] toHex=upper?toUpperHex:toLowerHex;
for(int i=0,j=0;i<data.length;i++){
int octet=data[i]&0xFF;
value[j++]=toHex[octet>>4];
value[j++]=toHex[octet&0xF];
}
return new String(value);
}
static final Encoder LOWER=new Encoder(false);
static final Encoder UPPER=new Encoder(true);
}
public static Encoder getEncoder(){
return Encoder.LOWER;
}
public static Encoder getUpperEncoder(){
return Encoder.UPPER;
}
//...
}
private static String bytesToHexString(byte[] bytes, int length) {
if (bytes == null || length == 0) return null;
StringBuilder ret = new StringBuilder(2*length);
for (int i = 0 ; i < length ; i++) {
int b;
b = 0x0f & (bytes[i] >> 4);
ret.append("0123456789abcdef".charAt(b));
b = 0x0f & bytes[i];
ret.append("0123456789abcdef".charAt(b));
}
return ret.toString();
}
Converts bytes data to hex characters
@param bytes byte array to be converted to hex string
@return byte String in hex format
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
참고 URL : https://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java
'ProgramingTip' 카테고리의 다른 글
System.Data.SQLite Close ()가 데이터베이스 파일을 해제하지 않습니다. (0) | 2020.10.04 |
---|---|
오류 구문 분석 /page.xhtml : 오류 추적 [line : 42] "nbsp"가 참조되지 않습니다. (0) | 2020.10.04 |
Android 개발 도구 v. 23으로 Eclipse 업데이트 (0) | 2020.10.03 |
.then () 체인에서 이전 약속 결과에 어떻게 액세스 할 수 있습니까? (0) | 2020.10.03 |
간단한 DI 코드가 아닌 IoC 컨테이너가 필요한 이유는 무엇입니까? (0) | 2020.10.03 |