How to convert a byte array to a hex string in Java?

后端 未结 27 3548
花落未央
花落未央 2020-11-21 04:19

I have a byte array filled with hex numbers and printing it the easy way is pretty pointless because there are many unprintable elements. What I need is the exact hexcode in

27条回答
  •  遇见更好的自我
    2020-11-21 05:04

    Can't find any solution on this page that doesn't

    1. Use a loop
    2. Use javax.xml.bind.DatatypeConverter which compiles fine but often throws java.lang.NoClassDefFoundError at runtime.

    Here's a solution which doesn't have the flaws above(no promises mine doesn't have other flaws though)

    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()));
        }
    }   
    

    I couldn't get this under 62 opcodes, but if you can live without 0 padding in case the first byte is less than 0x10, then the following solution only uses 23 opcodes. Really shows how "easy to implement yourself" solutions like "pad with a zero if string length is odd" can get pretty expensive if a native implementation is not already available(or in this case, if BigInteger had an option to prefix with zeros in 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);
    }
    

提交回复
热议问题