编码/解码字节如何在Java中工作?

时间:2016-08-21 00:45:50

标签: java encoding hex byte decoding

背景知识:我正在做一些色情挑战,我完成了https://cryptopals.com/sets/1/challenges/1但是我意识到我并没有学到我想要学习(或编码)的东西。

我使用Apache Commons Codec库进行Hex和Base64编码/解码。目标是解码十六进制字符串并将其重新编码为Base64。 "提示"在页面底部说"始终在原始字节上操作,从不在编码字符串上操作。仅使用hex和base64进行漂亮打印。"

这是我的答案......

private static Hex forHex = new Hex();
private static Base64 forBase64 = new Base64();

public static  byte[] hexDecode(String hex) throws DecoderException {
    byte[] rawBytes = forHex.decode(hex.getBytes());
    return rawBytes;
}
public static byte[] encodeB64(byte[] bytes) {
    byte[] base64Bytes = forBase64.encode(bytes);
    return base64Bytes;
}

public static void main(String[] args) throws DecoderException {

String hex = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";


//decode hex String to byte[]
byte[] myHexDecoded = hexDecode(hex);
String myHexDecodedString = new String(myHexDecoded);

//Lyrics from Queen's "Under Pressure"
System.out.println(myHexDecodedString);

//encode myHexDecoded to Base64 encoded byte[]
byte[] myHexEncoded = encodeB64(myHexDecoded);
String myB64String = new String(myHexEncoded);

//"pretty printing" of base64
System.out.println(myB64String);

}

......但我觉得自己被骗了。我没有学习如何解码编码为十六进制的字节,我也没有学习如何编码"纯"字节到Base64,我刚刚学会了如何使用库为我做一些事情。

如果我在Java中使用String然后获取其字节,我将如何将这些字节编码为十六进制?例如,以下代码片段转为" Hello" (这是可读的英语)到每个字符的字节值:

String s = "Hello";
char[] sChar = s.toCharArray();
byte[] sByte = new byte[sChar.length]
for(int i = 0; i < sChar.length; i++) {
    sByte[i] = (byte) sChar[i];
    System.out.println("sByte[" + i + "] = " +sByte[i]);
}

产生sByte [0] = 72,sByte [1] = 101,sByte [2] = 108,sByte [3] = 108,sByte [4] = 111

让我们使用&#39; o&#39;作为一个例子 - 我猜它的十进制版本是111 - 我只是采取其十进制版本并将其更改为其十六进制版本?

如果是这样,要解码,我是否一次只取十六进制字符串2中的字符,将它们分解为十进制值,然后转换为ASCII?它总是ASCII吗?

1 个答案:

答案 0 :(得分:2)

  

进行解码,我是一次只取十六进制字符串2中的字符,将它们分解为十进制值,然后转换为ASCII?它总是ASCII吗?

没有。你一次取2个字符,将字符'0'转换为数值0,将字符'1'转换为数值1,...,字符'a'(或'A',取决于哪个想要支持的编码)到数值10,...,字符'f'或'F'到数值15。

然后将第一个数值乘以16,然后将其添加到第二个数值以获取字节的无符号整数值。然后将无符号整数值转换为有符号字节。

ASCII与此算法无关。

要了解它在实践中是如何完成的,因为commons-codec是开源的,你可以看一下它的实现。