Java code To convert byte to Hexadecimal

后端 未结 19 2215
我寻月下人不归
我寻月下人不归 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:44

    Creating (and destroying) a bunch of String instances is not a good way if performance is an issue.

    Please ignore those verbose (duplicate) arguments checking statements (ifs). That's for (another) educational purposes.

    Full maven project: http://jinahya.googlecode.com/svn/trunk/com.googlecode.jinahya/hex-codec/

    Encoding...

    /**
     * Encodes a single nibble.
     *
     * @param decoded the nibble to encode.
     *
     * @return the encoded half octet.
     */
    protected static int encodeHalf(final int decoded) {
    
        switch (decoded) {
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
            case 0x04:
            case 0x05:
            case 0x06:
            case 0x07:
            case 0x08:
            case 0x09:
                return decoded + 0x30; // 0x30('0') - 0x39('9')
            case 0x0A:
            case 0x0B:
            case 0x0C:
            case 0x0D:
            case 0x0E:
            case 0x0F:
                return decoded + 0x57; // 0x41('a') - 0x46('f')
            default:
                throw new IllegalArgumentException("illegal half: " + decoded);
        }
    }
    
    
    /**
     * Encodes a single octet into two nibbles.
     *
     * @param decoded the octet to encode.
     * @param encoded the array to which each encoded nibbles are written.
     * @param offset the offset in the array.
     */
    protected static void encodeSingle(final int decoded, final byte[] encoded,
                                       final int offset) {
    
        if (encoded == null) {
            throw new IllegalArgumentException("null encoded");
        }
    
        if (encoded.length < 2) {
            // not required
            throw new IllegalArgumentException(
                "encoded.length(" + encoded.length + ") < 2");
        }
    
        if (offset < 0) {
            throw new IllegalArgumentException("offset(" + offset + ") < 0");
        }
    
        if (offset >= encoded.length - 1) {
            throw new IllegalArgumentException(
                "offset(" + offset + ") >= encoded.length(" + encoded.length
                + ") - 1");
        }
    
        encoded[offset] = (byte) encodeHalf((decoded >> 4) & 0x0F);
        encoded[offset + 1] = (byte) encodeHalf(decoded & 0x0F);
    }
    
    
    /**
     * Decodes given sequence of octets into a sequence of nibbles.
     *
     * @param decoded the octets to encode
     *
     * @return the encoded nibbles.
     */
    protected static byte[] encodeMultiple(final byte[] decoded) {
    
        if (decoded == null) {
            throw new IllegalArgumentException("null decoded");
        }
    
        final byte[] encoded = new byte[decoded.length << 1];
    
        int offset = 0;
        for (int i = 0; i < decoded.length; i++) {
            encodeSingle(decoded[i], encoded, offset);
            offset += 2;
        }
    
        return encoded;
    }
    
    
    /**
     * Encodes given sequence of octets into a sequence of nibbles.
     *
     * @param decoded the octets to encode.
     *
     * @return the encoded nibbles.
     */
    public byte[] encode(final byte[] decoded) {
    
        return encodeMultiple(decoded);
    }
    

    Decoding...

    /**
     * Decodes a single nibble.
     *
     * @param encoded the nibble to decode.
     *
     * @return the decoded half octet.
     */
    protected static int decodeHalf(final int encoded) {
    
        switch (encoded) {
            case 0x30: // '0'
            case 0x31: // '1'
            case 0x32: // '2'
            case 0x33: // '3'
            case 0x34: // '4'
            case 0x35: // '5'
            case 0x36: // '6'
            case 0x37: // '7'
            case 0x38: // '8'
            case 0x39: // '9'
                return encoded - 0x30;
            case 0x41: // 'A'
            case 0x42: // 'B'
            case 0x43: // 'C'
            case 0x44: // 'D'
            case 0x45: // 'E'
            case 0x46: // 'F'
                return encoded - 0x37;
            case 0x61: // 'a'
            case 0x62: // 'b'
            case 0x63: // 'c'
            case 0x64: // 'd'
            case 0x65: // 'e'
            case 0x66: // 'f'
                return encoded - 0x57;
            default:
                throw new IllegalArgumentException("illegal half: " + encoded);
        }
    }
    
    
    /**
     * Decodes two nibbles into a single octet.
     *
     * @param encoded the nibble array.
     * @param offset the offset in the array.
     *
     * @return decoded octet.
     */
    protected static int decodeSingle(final byte[] encoded, final int offset) {
    
        if (encoded == null) {
            throw new IllegalArgumentException("null encoded");
        }
    
        if (encoded.length < 2) {
            // not required
            throw new IllegalArgumentException(
                "encoded.length(" + encoded.length + ") < 2");
        }
    
        if (offset < 0) {
            throw new IllegalArgumentException("offset(" + offset + ") < 0");
        }
    
        if (offset >= encoded.length - 1) {
            throw new IllegalArgumentException(
                "offset(" + offset + ") >= encoded.length(" + encoded.length
                + ") - 1");
        }
    
        return (decodeHalf(encoded[offset]) << 4)
               | decodeHalf(encoded[offset + 1]);
    }
    
    
    /**
     * Encodes given sequence of nibbles into a sequence of octets.
     *
     * @param encoded the nibbles to decode.
     *
     * @return the encoded octets.
     */
    protected static byte[] decodeMultiple(final byte[] encoded) {
    
        if (encoded == null) {
            throw new IllegalArgumentException("null encoded");
        }
    
        if ((encoded.length & 0x01) == 0x01) {
            throw new IllegalArgumentException(
                "encoded.length(" + encoded.length + ") is not even");
        }
    
        final byte[] decoded = new byte[encoded.length >> 1];
    
        int offset = 0;
        for (int i = 0; i < decoded.length; i++) {
            decoded[i] = (byte) decodeSingle(encoded, offset);
            offset += 2;
        }
    
        return decoded;
    }
    
    
    /**
     * Decodes given sequence of nibbles into a sequence of octets.
     *
     * @param encoded the nibbles to decode.
     *
     * @return the decoded octets.
     */
    public byte[] decode(final byte[] encoded) {
    
        return decodeMultiple(encoded);
    }
    
    0 讨论(0)
  • 2020-11-22 17:44

    Just like some other answers, I recommend to use String.format() and BigInteger. But to interpret the byte array as big-endian binary representation instead of two's-complement binary representation (with signum and incomplete use of possible hex values range) use BigInteger(int signum, byte[] magnitude), not BigInteger(byte[] val).

    For example, for a byte array of length 8 use:

    String.format("%016X", new BigInteger(1,bytes))
    

    Advantages:

    • leading zeros
    • no signum
    • only built-in functions
    • only one line of code

    Disadvantage:

    • there might be more efficient ways to do that

    Example:

    byte[] bytes = new byte[8];
    Random r = new Random();
    System.out.println("big-endian       | two's-complement");
    System.out.println("-----------------|-----------------");
    for (int i = 0; i < 10; i++) {
        r.nextBytes(bytes);
        System.out.print(String.format("%016X", new BigInteger(1,bytes)));
        System.out.print(" | ");
        System.out.print(String.format("%016X", new BigInteger(bytes)));
        System.out.println();
    }
    

    Example output:

    big-endian       | two's-complement
    -----------------|-----------------
    3971B56BC7C80590 | 3971B56BC7C80590
    64D3C133C86CCBDC | 64D3C133C86CCBDC
    B232EFD5BC40FA61 | -4DCD102A43BF059F
    CD350CC7DF7C9731 | -32CAF338208368CF
    82CDC9ECC1BC8EED | -7D3236133E437113
    F438C8C34911A7F5 | -BC7373CB6EE580B
    5E99738BE6ACE798 | 5E99738BE6ACE798
    A565FE5CE43AA8DD | -5A9A01A31BC55723
    032EBA783D2E9A9F | 032EBA783D2E9A9F
    8FDAA07263217ABA | -70255F8D9CDE8546
    
    0 讨论(0)
  • 2020-11-22 17:45

    This is the code that I've found to run the fastest so far. I ran it on 109015 byte arrays of length 32, in 23ms. I was running it on a VM so it'll probably run faster on bare metal.

    public static final char[] HEX_DIGITS =         {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    
    public static char[] encodeHex( final byte[] data ){
        final int l = data.length;
        final char[] out = new char[l<<1];
        for( int i=0,j=0; i<l; i++ ){
            out[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
            out[j++] = HEX_DIGITS[0x0F & data[i]];
        }
        return out;
    }
    

    Then you can just do

    String s = new String( encodeHex(myByteArray) );
    
    0 讨论(0)
  • 2020-11-22 17:46

    This is a very fast way. No external libaries needed.

    final protected static char[] HEXARRAY = "0123456789abcdef".toCharArray();
    
        public static String encodeHexString( 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] = HEXARRAY[v >>> 4];
                hexChars[j * 2 + 1] = HEXARRAY[v & 0x0F];
            }
            return new String(hexChars);
        }
    
    0 讨论(0)
  • 2020-11-22 17:47
    BigInteger n = new BigInteger(byteArray);
    String hexa = n.toString(16));
    
    0 讨论(0)
  • 2020-11-22 17:47

    I couldn't figure out what exactly you meant by byte String, but here are some conversions from byte to String and vice versa, of course there is a lot more on the official documentations

    Integer intValue = 149;
    

    The corresponding byte value is:

    Byte byteValue = intValue.byteValue(); // this will convert the rightmost byte of the intValue to byte, because Byte is an 8 bit object and Integer is at least 16 bit, and it will give you a signed number in this case -107
    

    get the integer value back from a Byte variable:

    Integer anInt = byteValue.intValue(); // This will convert the byteValue variable to a signed Integer
    

    From Byte and Integer to hex String:
    This is the way I do it:

    Integer anInt = 149
    Byte aByte = anInt.byteValue();
    
    String hexFromInt = "".format("0x%x", anInt); // This will output 0x95
    String hexFromByte = "".format("0x%x", aByte); // This will output 0x95
    

    Converting an array of bytes to a hex string:
    As far as I know there is no simple function to convert all the elements inside an array of some Object to elements of another Object, So you have to do it yourself. You can use the following functions:

    From byte[] to String:

        public static String byteArrayToHexString(byte[] byteArray){
            String hexString = "";
    
            for(int i = 0; i < byteArray.length; i++){
                String thisByte = "".format("%x", byteArray[i]);
                hexString += thisByte;
            }
    
            return hexString;
        }
    

    And from hex string to byte[]:

    public static byte[] hexStringToByteArray(String hexString){
        byte[] bytes = new byte[hexString.length() / 2];
    
        for(int i = 0; i < hexString.length(); i += 2){
            String sub = hexString.substring(i, i + 2);
            Integer intVal = Integer.parseInt(sub, 16);
            bytes[i / 2] = intVal.byteValue();
            String hex = "".format("0x%x", bytes[i / 2]);
        }
    
        return bytes;
    }  
    

    It is too late but I hope this could help some others ;)

    0 讨论(0)
提交回复
热议问题