我遇到了一个遗留代码段,将字节数组编码为十六进制字符串,这种代码正在生产中,并且从未引起问题。
这段代码用作:
- 我们对用户密码进行加密。加密器返回一个
byte[]
。 - 我们使用此编码器代码将
byte[]
转换为十六进制字符串,然后在属性文件中使用String
表示形式,等等。
但是,昨天我们输入了一个密码,该密码的加密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;
}
}
旧版代码输出的编码值为:0ad21588c0a2c2fc68dc859197fc78cd
,而正确的期望值应为:a0d21588c0a2c2fc68dc859197fc78cd
。
我正试图了解编码器出了什么问题,需要一些帮助来理解。