Tagged: base16
Hexadecimal Encoding/Decoding with Java
Representing numbers in hexadecimal form, at least in programming, might still be a very difficult problem. There are plenty of googled results for how we do it in any languages.
DatatypeConverter from JAXB
First and foremost way is definitely using one of existing classes and methods in JDK.
- public static byte[] parseHexBinary(String lexicalXSDHexBinary)
- public static String printHexBinary(byte[] val)
Here comes OpenJDK’s implemention of those method.
public byte[] parseHexBinary(String s) { final int len = s.length(); // "111" is not a valid hex encoding. if (len % 2 != 0) { throw new IllegalArgumentException("hexBinary needs to be even-length: " + s); } byte[] out = new byte[len / 2]; for (int i = 0; i < len; i += 2) { int h = hexToBin(s.charAt(i)); int l = hexToBin(s.charAt(i + 1)); if (h == -1 || l == -1) { throw new IllegalArgumentException("contains illegal character for hexBinary: " + s); } out[i / 2] = (byte) (h * 16 + l); } return out; } private static int hexToBin(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 char[] hexCode = "0123456789ABCDEF".toCharArray(); public String printHexBinary(byte[] data) { StringBuilder r = new StringBuilder(data.length * 2); for (byte b : data) { r.append(hexCode[(b >> 4) & 0xF]); r.append(hexCode[(b & 0xF)]); } return r.toString(); }
half
number (4bit) | character (8bit) |
---|---|
0x0 ( 0) |
0x30 ('0') |
0x1 ( 1) |
0x31 ('1') |
0x2 ( 2) |
0x32 ('2') |
0x3 ( 3) |
0x33 ('3') |
0x4 ( 4) |
0x34 ('4') |
0x5 ( 5) |
0x35 ('5') |
0x6 ( 6) |
0x36 ('6') |
0x7 ( 7) |
0x37 ('7') |
0x8 ( 8) |
0x38 ('8') |
0x9 ( 9) |
0x39 ('9') |
0xA (10) |
0x41 ('A') |
0xB (11) |
0x42 ('B') |
0xC (12) |
0x43 ('C') |
0xA (13) |
0x44 ('D') |
0xE (14) |
0x45 ('E') |
0xF (15) |
0x46 ('F') |
protected static int encodeHalf(final int decoded) { if (decoded < 0x0A) { return decoded + 0x30; } else { return decoded + 0x37; } } protected static int decodeHalf(final int encoded) { if (encoded < 0x41) { return encoded - 0x30; } else { return encoded - 0x37; } }
single
number (8bit) | character (16bit) |
---|---|
0x00 ( 0) |
0x30 0x30 ('00') |
.... ( .) |
.... .... ('..') |
0x09 ( 9) |
0x30 0x39 ('09') |
0x0A ( 10) |
0x30 0x41 ('0A') |
.... ( ..) |
.... .... ('..') |
0x0F ( 15) |
0x30 0x46 ('0F') |
0x10 ( 16) |
0x31 0x30 ('10') |
.... ( ..) |
.... .... ('..') |
0x63 ( 99) |
0x36 0x33 ('63') |
0x64 (100) |
0x36 0x34 ('64') |
0xC7 (199) |
0x43 0x37 ('C7') |
0xC8 (200) |
0x43 0x38 ('C8') |
0xC9 (201) |
0x43 0x39 ('C9') |
.... (...) |
.... .... ('..') |
0xFF (255) |
0x46 0x46 ('FF') |
protected static byte[] encodeSingle(final int decoded) { final byte[] encoded = new byte[2]; encoded[0] = (byte) encodeHalf(decoded >> 4); encoded[1] = (byte) encodeHalf(decoded & 0x0F); return encoded; } protected static int decodeSingle(final byte[] encoded) { final int high = decodeHalf(encoded[0] & 0xFF); final int low = decodeHalf(encoded[1] & 0xFF); return (high << 4 | low); }
multiple
protected static void encodeSingle(final int decoded, final byte[] encoded, final int offset); protected static int decodeSingle(final byte[] encoded, final int offset); protected static byte[] encodeMultiple(final byte[] decoded); protected static byte[] decodeMultiple(final byte[] encoded);
sources
$ svn co http://jinahya.googlecode.com/svn/trunk/com.googlecode.jinahya/hex-codec/ hex-codec
RFC 4648 The Base16, Base32, and Base64 Data Encodings
RFC 4648 The Base16, Base32, and Base64 Data Encodings
name | bits/char | bytes/word | chars/word | pad | notes |
---|---|---|---|---|---|
base16 (hex) | 4 | 1 | 2 | N/A | |
base32 | 5 | 5 | 8 | YES | |
base32hex | 5 | 5 | 8 | YES | |
base64 | 6 | 3 | 4 | YES | |
base64url | 6 | 3 | 4 | NO |
Base.java
Base16.java
Base32.java
Base32Hex.java
Base64.java
Base64Url.java
import java.io.IOException; import java.util.Arrays; import jinahya.rfc4648.*; public class Test { private static final PrintStream UTF8; static { try { UTF8 = new PrintStream(System.out, true, "UTF-8"); } catch (UnsupportedEncodingException uee) { throw new InstantiationError( "What can I do to make you love me?"); } } private static final String[] WELCOMES = { "Salaam", "Dobrodošli", "歡迎", "欢迎", "歡迎", "Vítáme tĕ", "Velkommen", "Welkom", "Bienvenue", "Wolkom", "Willkommen", "Καλώς ορίσατε", "Aloha", "Shalom", "Benvenuto", "ようこそ", "환영합니다", "Тавтай морилогтун", "Bem-vindo", "Bem-vinda", "Bienvenido", "Välkommen", "Mabuhay", "Swaagatham", "Suswaagatham", "Merhaba"}; public static void main(String[] args) throws IOException { if (args.length == 0) { test(WELCOMES); } else { test(args); } } private static void test(final String[] strings) throws IOException { for (String string : strings) { System.out.printf("%1$5s: %2$s\n", "input", string); final byte[] original = string.getBytes("UTF-8"); System.out.printf("%1$5s: ", "UTF-8"); for (byte b : original) { System.out.printf("%1$s", Integer.toHexString(b & 0xFF)); } System.out.printf("\n"); test("base64", new Base64(), original); test("base64url", new Base64URL(), original); test("base32", new Base32(), original); test("base32hex", new Base32HEX(), original); test("base16", new Base16(), original); } } private static void test(final String name, final Base base, final byte[] original) throws IOException { final char[] encoded = base.encode(original); System.out.printf("\t%1$10s: %2$s\n", name, new String(encoded)); final byte[] decoded = base.decode(encoded); assert Arrays.equals(decoded, original) : "fail"; } }
input: Salaam UTF-8: 53616c61616d base64: U2FsYWFt base64url: U2FsYWFt base32: KNQWYYLBNU====== base32hex: ADGMOOB1DK====== base16: 53616C61616D input: Dobrodošli UTF-8: 446f62726f646fc5a16c69 base64: RG9icm9kb8WhbGk= base64url: RG9icm9kb8WhbGk base32: IRXWE4TPMRX4LILMNE====== base32hex: 8HNM4SJFCHNSB8BCD4====== base16: 446F62726F646FC5A16C69 input: 歡迎 UTF-8: e6ada1e8bf8e base64: 5q2h6L+O base64url: 5q2h6L-O base32: 42W2D2F7RY====== base32hex: SQMQ3Q5VHO====== base16: E6ADA1E8BF8E input: 欢迎 UTF-8: e6aca2e8bf8e base64: 5qyi6L+O base64url: 5qyi6L-O base32: 42WKF2F7RY====== base32hex: SQMA5Q5VHO====== base16: E6ACA2E8BF8E input: 歡迎 UTF-8: e6ada1e8bf8e base64: 5q2h6L+O base64url: 5q2h6L-O base32: 42W2D2F7RY====== base32hex: SQMQ3Q5VHO====== base16: E6ADA1E8BF8E input: Vítáme tĕ UTF-8: 56c3ad74c3a16d652074c495 base64: VsOtdMOhbWUgdMSV base64url: VsOtdMOhbWUgdMSV base32: K3B225GDUFWWKIDUYSKQ==== base32hex: AR1QQT63K5MMA83KOIAG==== base16: 56C3AD74C3A16D652074C495 input: Velkommen UTF-8: 56656c6b6f6d6d656e base64: VmVsa29tbWVu base64url: VmVsa29tbWVu base32: KZSWY23PNVWWK3Q= base32hex: APIMOQRFDLMMARG= base16: 56656C6B6F6D6D656E input: Welkom UTF-8: 57656c6b6f6d base64: V2Vsa29t base64url: V2Vsa29t base32: K5SWY23PNU====== base32hex: ATIMOQRFDK====== base16: 57656C6B6F6D input: Bienvenue UTF-8: 4269656e76656e7565 base64: QmllbnZlbnVl base64url: QmllbnZlbnVl base32: IJUWK3TWMVXHKZI= base32hex: 89KMARJMCLN7AP8= base16: 4269656E76656E7565 input: Wolkom UTF-8: 576f6c6b6f6d base64: V29sa29t base64url: V29sa29t base32: K5XWY23PNU====== base32hex: ATNMOQRFDK====== base16: 576F6C6B6F6D input: Willkommen UTF-8: 57696c6c6b6f6d6d656e base64: V2lsbGtvbW1lbg== base64url: V2lsbGtvbW1lbg base32: K5UWY3DLN5WW2ZLO base32hex: ATKMOR3BDTMMQPBE base16: 57696C6C6B6F6D6D656E input: Καλώς ορίσατε UTF-8: ce9aceb1cebbcf8ecf8220cebfcf81ceafcf83ceb1cf84ceb5 base64: zprOsc67z47PgiDOv8+Bzq/Pg86xz4TOtQ== base64url: zprOsc67z47PgiDOv8-Bzq_Pg86xz4TOtQ base32: Z2NM5MOOXPHY5T4CEDHL7T4BZ2X47A6OWHHYJTVV base32hex: PQDCTCEENF7OTJS2437BVJS1PQNSV0UEM77O9JLL base16: CE9ACEB1CEBBCF8ECF8220CEBFCF81CEAFCF83CEB1CF84CEB5 input: Aloha UTF-8: 416c6f6861 base64: QWxvaGE= base64url: QWxvaGE base32: IFWG62DB base32hex: 85M6UQ31 base16: 416C6F6861 input: Shalom UTF-8: 5368616c6f6d base64: U2hhbG9t base64url: U2hhbG9t base32: KNUGC3DPNU====== base32hex: ADK62R3FDK====== base16: 5368616C6F6D input: Benvenuto UTF-8: 42656e76656e75746f base64: QmVudmVudXRv base64url: QmVudmVudXRv base32: IJSW45TFNZ2XI3Y= base32hex: 89IMSTJ5DPQN8RO= base16: 42656E76656E75746F input: ようこそ UTF-8: e38288e38186e38193e3819d base64: 44KI44GG44GT44Gd base64url: 44KI44GG44GT44Gd base32: 4OBIRY4BQ3RYDE7DQGOQ==== base32hex: SE18HOS1GRHO34V3G6EG==== base16: E38288E38186E38193E3819D input: 환영합니다 UTF-8: ed9998ec9881ed95a9eb8b88eb8ba4 base64: 7ZmY7JiB7ZWp64uI64uk base64url: 7ZmY7JiB7ZWp64uI64uk base32: 5WMZR3EYQHWZLKPLROEOXC5E base32hex: TMCPHR4OG7MPBAFBHE4EN2T4 base16: ED9998EC9881ED95A9EB8B88EB8BA4 input: Тавтай морилогтун UTF-8: d0a2d0b0d0b2d182d0b0d0b920d0bcd0bed180d0b8d0bbd0bed0b3d182d183d0bd base64: 0KLQsNCy0YLQsNC5INC80L7RgNC40LvQvtCz0YLRg9C9 base64url: 0KLQsNCy0YLQsNC5INC80L7RgNC40LvQvtCz0YLRg9C9 base32: 2CRNBMGQWLIYFUFQ2C4SBUF42C7NDAGQXDILXUF62CZ5DAWRQPIL2=== base32hex: Q2HD1C6GMB8O5K5GQ2SI1K5SQ2VD306GN38BNK5UQ2PT30MHGF8BQ=== base16: D0A2D0B0D0B2D182D0B0D0B920D0BCD0BED180D0B8D0BBD0BED0B3D182D183D0BD input: Bem-vindo UTF-8: 42656d2d76696e646f base64: QmVtLXZpbmRv base64url: QmVtLXZpbmRv base32: IJSW2LLWNFXGI3Y= base32hex: 89IMQBBMD5N68RO= base16: 42656D2D76696E646F input: Bem-vinda UTF-8: 42656d2d76696e6461 base64: QmVtLXZpbmRh base64url: QmVtLXZpbmRh base32: IJSW2LLWNFXGIYI= base32hex: 89IMQBBMD5N68O8= base16: 42656D2D76696E6461 input: Bienvenido UTF-8: 4269656e76656e69646f base64: QmllbnZlbmlkbw== base64url: QmllbnZlbmlkbw base32: IJUWK3TWMVXGSZDP base32hex: 89KMARJMCLN6IP3F base16: 4269656E76656E69646F input: Välkommen UTF-8: 56c3a46c6b6f6d6d656e base64: VsOkbGtvbW1lbg== base64url: VsOkbGtvbW1lbg base32: K3B2I3DLN5WW2ZLO base32hex: AR1Q8R3BDTMMQPBE base16: 56C3A46C6B6F6D6D656E input: Mabuhay UTF-8: 4d616275686179 base64: TWFidWhheQ== base64url: TWFidWhheQ base32: JVQWE5LIMF4Q==== base32hex: 9LGM4TB8C5SG==== base16: 4D616275686179 input: Swaagatham UTF-8: 5377616167617468616d base64: U3dhYWdhdGhhbQ== base64url: U3dhYWdhdGhhbQ base32: KN3WCYLHMF2GQYLN base32hex: ADRM2OB7C5Q6GOBD base16: 5377616167617468616D input: Suswaagatham UTF-8: 53757377616167617468616d base64: U3Vzd2FhZ2F0aGFt base64url: U3Vzd2FhZ2F0aGFt base32: KN2XG53BMFTWC5DIMFWQ==== base32hex: ADQN6TR1C5JM2T38C5MG==== base16: 53757377616167617468616D input: Merhaba UTF-8: 4d657268616261 base64: TWVyaGFiYQ== base64url: TWVyaGFiYQ base32: JVSXE2DBMJQQ==== base32hex: 9LIN4Q31C9GG==== base16: 4D657268616261