Java code To convert byte to Hexadecimal

后端 未结 19 2214
我寻月下人不归
我寻月下人不归 2020-11-22 17:26

I have an array of bytes. I want each byte String of that array to be converted to its corresponding hexadecimal values.

Is there any function in Java to convert a b

相关标签:
19条回答
  • 2020-11-22 17:47

    There's your fast method:

        private static final String[] hexes = 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 hexes[b&0xFF];
        }
    
    0 讨论(0)
  • 2020-11-22 17:49

    The Best solution is this badass one-liner:

    String hex=DatatypeConverter.printHexBinary(byte[] b);
    

    as mentioned here

    0 讨论(0)
  • 2020-11-22 17:51

    If you want a constant-width hex representation, i.e. 0A instead of A, so that you can recover the bytes unambiguously, try format():

    StringBuilder result = new StringBuilder();
    for (byte bb : byteArray) {
        result.append(String.format("%02X", bb));
    }
    return result.toString();
    
    0 讨论(0)
  • 2020-11-22 17:52

    The fastest way i've yet found to do this is the following:

    private static final String    HEXES    = "0123456789ABCDEF";
    
    static String getHex(byte[] raw) {
        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();
    }
    

    It's ~ 50x faster than String.format. if you want to test it:

    public class MyTest{
        private static final String    HEXES        = "0123456789ABCDEF";
    
        @Test
        public void test_get_hex() {
            byte[] raw = {
                (byte) 0xd0, (byte) 0x0b, (byte) 0x01, (byte) 0x2a, (byte) 0x63,
                (byte) 0x78, (byte) 0x01, (byte) 0x2e, (byte) 0xe3, (byte) 0x6c,
                (byte) 0xd2, (byte) 0xb0, (byte) 0x78, (byte) 0x51, (byte) 0x73,
                (byte) 0x34, (byte) 0xaf, (byte) 0xbb, (byte) 0xa0, (byte) 0x9f,
                (byte) 0xc3, (byte) 0xa9, (byte) 0x00, (byte) 0x1e, (byte) 0xd5,
                (byte) 0x4b, (byte) 0x89, (byte) 0xa3, (byte) 0x45, (byte) 0x35,
                (byte) 0xd6, (byte) 0x10,
            };
    
            int N = 77777;
            long t;
    
            {
                t = System.currentTimeMillis();
                for (int i = 0; i < N; i++) {
                    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)));
                    }
                    hex.toString();
                }
                System.out.println(System.currentTimeMillis() - t); // 50
            }
    
            {
                t = System.currentTimeMillis();
                for (int i = 0; i < N; i++) {
                    StringBuilder hex = new StringBuilder(2 * raw.length);
                    for (byte b : raw) {
                        hex.append(String.format("%02X", b));
                    }
                    hex.toString();
                }
                System.out.println(System.currentTimeMillis() - t); // 2535
            }
    
        }
    }
    

    Edit: Just found something just a lil faster and that holds on one line but is not compatible with JRE 9. Use at your own risks

    import javax.xml.bind.DatatypeConverter;
    
    DatatypeConverter.printHexBinary(raw);
    
    0 讨论(0)
  • 2020-11-22 17:54

    You can use the method from Bouncy Castle Provider library:

    org.bouncycastle.util.encoders.Hex.toHexString(byteArray);
    

    The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5 to JDK 1.8.

    Maven dependency:

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.60</version>
    </dependency>
    

    or from Apache Commons Codec:

    org.apache.commons.codec.binary.Hex.encodeHexString(byteArray);
    

    The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.

    Maven dependency:

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.11</version>
    </dependency>
    
    0 讨论(0)
  • 2020-11-22 17:55
        byte[] bytes = {-1, 0, 1, 2, 3 };
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        System.out.println(sb.toString());
        // prints "FF 00 01 02 03 "
    

    See also

    • java.util.Formatter syntax
      • %[flags][width]conversion
        • Flag '0' - The result will be zero-padded
        • Width 2
        • Conversion 'X' - The result is formatted as a hexadecimal integer, uppercase

    Looking at the text of the question, it's also possible that this is what is requested:

        String[] arr = {"-1", "0", "10", "20" };
        for (int i = 0; i < arr.length; i++) {
            arr[i] = String.format("%02x", Byte.parseByte(arr[i]));
        }
        System.out.println(java.util.Arrays.toString(arr));
        // prints "[ff, 00, 0a, 14]"
    

    Several answers here uses Integer.toHexString(int); this is doable, but with some caveats. Since the parameter is an int, a widening primitive conversion is performed to the byte argument, which involves sign extension.

        byte b = -1;
        System.out.println(Integer.toHexString(b));
        // prints "ffffffff"
    

    The 8-bit byte, which is signed in Java, is sign-extended to a 32-bit int. To effectively undo this sign extension, one can mask the byte with 0xFF.

        byte b = -1;
        System.out.println(Integer.toHexString(b & 0xFF));
        // prints "ff"
    

    Another issue with using toHexString is that it doesn't pad with zeroes:

        byte b = 10;
        System.out.println(Integer.toHexString(b & 0xFF));
        // prints "a"
    

    Both factors combined should make the String.format solution more preferrable.

    References

    • JLS 4.2.1 Integral Types and Values
      • For byte, from -128 to 127, inclusive
    • JLS 5.1.2 Widening Primitive Conversion
    0 讨论(0)
提交回复
热议问题