Java 将字节数组编码为十六进制字符串
我遇到了一段将字节数组编码为十六进制字符串的遗留代码,该代码正在生产中,从未引起任何问题 这段代码用作:Java 将字节数组编码为十六进制字符串,java,arrays,encoding,hex,Java,Arrays,Encoding,Hex,我遇到了一段将字节数组编码为十六进制字符串的遗留代码,该代码正在生产中,从未引起任何问题 这段代码用作: 我们加密用户密码。加密程序返回一个字节[] 我们使用此编码器代码将字节[]转换为十六进制字符串,然后在属性文件中使用该字符串表示形式,依此类推 然而,昨天我们发现了一个密码,其加密的byte[]版本编码不正确 import java.math.BigInteger; import java.util.HashMap; import org.apache.commons.codec.De
- 我们加密用户密码。加密程序返回一个
字节[]
- 我们使用此编码器代码将
转换为十六进制字符串,然后在属性文件中使用该字节[]
表示形式,依此类推字符串
byte[]
版本编码不正确
import java.math.BigInteger;
import java.util.HashMap;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
public class ByteArrayToHexEncoder {
public static void main(String[] args) throws DecoderException {
String hexString = "a0d21588c0a2c2fc68dc859197fc78cd"; // correct hex representation
// equivalent byte array: this is the byte array returned by the encryptor
byte[] byteArray = Hex.decodeHex(hexString.toCharArray());
// legacy encoder
System.out.println("Legacy code encodes as: " + encodeHexBytesWithPadding(byteArray));
// commons-codec encoder
System.out.println("Commons codec encode as: " + new String(Hex.encodeHex(byteArray)));
}
private static final String PADDING_ZEROS =
"0000000000000000000000000000000000000000000000000000000000000";
private static final HashMap<Integer, Character> MAP_OF_HEX = new HashMap<>();
static {
MAP_OF_HEX.put(0, '0');
MAP_OF_HEX.put(1, '1');
MAP_OF_HEX.put(2, '2');
MAP_OF_HEX.put(3, '3');
MAP_OF_HEX.put(4, '4');
MAP_OF_HEX.put(5, '5');
MAP_OF_HEX.put(6, '6');
MAP_OF_HEX.put(7, '7');
MAP_OF_HEX.put(8, '8');
MAP_OF_HEX.put(9, '9');
MAP_OF_HEX.put(10, 'a');
MAP_OF_HEX.put(11, 'b');
MAP_OF_HEX.put(12, 'c');
MAP_OF_HEX.put(13, 'd');
MAP_OF_HEX.put(14, 'e');
MAP_OF_HEX.put(15, 'f');
}
public static String encodeHexBytesWithPadding(byte[] inputByteArray) {
String encodedValue = encodeHexBytes(inputByteArray);
int expectedSize = inputByteArray.length * 2;
if (encodedValue.length() < expectedSize) {
int zerosToPad = expectedSize - encodedValue.length();
encodedValue = PADDING_ZEROS.substring(0, zerosToPad) + encodedValue;
}
return encodedValue;
}
public static String encodeHexBytes(byte[] inputByteArray) {
String encodedValue;
if (inputByteArray[0] < 0) {
// Something is wrong here! Don't know what!
byte oldValue = inputByteArray[0];
inputByteArray[0] = (byte) (oldValue & 0x0F);
int nibble = (oldValue >> 4) & 0x0F;
encodedValue = new BigInteger(inputByteArray).toString(16);
inputByteArray[0] = oldValue;
encodedValue = MAP_OF_HEX.get(nibble) + encodedValue;
} else {
encodedValue = new BigInteger(inputByteArray).toString(16);
}
return encodedValue;
}
}
import java.math.biginger;
导入java.util.HashMap;
导入org.apache.commons.codec.DecoderException;
导入org.apache.commons.codec.binary.Hex;
公共类ByteArrayToHexEncoder{
公共静态void main(字符串[]args)引发Decode异常{
字符串hexString=“a0d21588c0a2c2fc68dc859197fc78cd”;//正确的十六进制表示法
//等效字节数组:这是加密程序返回的字节数组
字节[]byteArray=Hex.decodeHex(hexString.ToCharray());
//传统编码器
System.out.println(“遗留代码编码为:”+encodeHexBytesWithPadding(byteArray));
//通用编解码器
System.out.println(“Commons编解码器编码为:”+新字符串(Hex.encodeHex(byteArray));
}
私有静态最终字符串填充0=
"0000000000000000000000000000000000000000000000000000000000000";
私有静态最终HashMap映射_OF_HEX=新HashMap();
静止的{
映射十六进制put(0,'0');
映射十六进制put(1,'1');
映射十六进制put(2,'2');
映射十六进制put(3,'3');
映射十六进制put(4,'4');
映射十六进制put(5,'5');
映射十六进制put(6,'6');
映射十六进制put(7,'7');
映射十六进制put(8,'8');
映射十六进制put(9,'9');
映射十六进制put(10,'a');
映射十六进制put(11,'b');
映射十六进制put(12,'c');
十六进制put(13,'d')的映射;
映射十六进制put(14,'e');
映射十六进制put(15,'f');
}
公共静态字符串encodeHexBytesWithPadding(字节[]inputByteArray){
字符串encodedValue=encodeHexBytes(inputByteArray);
int expectedSize=inputByteArray.length*2;
if(encodedValue.length()>4)&0x0F;
encodedValue=新的大整数(inputByteArray).toString(16);
inputByteArray[0]=旧值;
encodedValue=十六进制get(半字节)+encodedValue的映射;
}否则{
encodedValue=新的大整数(inputByteArray).toString(16);
}
返回编码值;
}
}
传统代码将编码值输出为:0ad21588c0a2c2fc68dc859197fc78cd
,而正确的预期值应为:a0d21588c0a2c2fc68dc859197fc78cd
我正在试图理解编码器的错误,需要一些帮助来理解。biginger(byte[])
构造函数用于处理最高有效位也表示符号的位置。通用编解码器将每个字节转换成十六进制表示,最高有效位没有特殊意义
if(inputByteArray[0]<0)
分支中的旧代码尝试修改byte[]
输入中的第一个字节,可能是为了解决以两个补码的形式表示负数的问题,例如将-1
表示为ff
。不幸的是,这在旧代码中实现不正确:
String input = "a000000001";
byte[] bytes = Hex.decodeHex(input.toCharArray());
System.out.println(encodeHexBytesWithPadding(bytes));
System.out.println(Hex.encodeHexString(bytes));
将打印
00000000a1
a000000001
显示遗留代码值完全错误
这里没有太多需要补救的地方,请改用
Hex.encodeHexString()
或检查。请您再解释一下。。如果修改第一个字节以忽略2补码形式的符号是错误的?