Reputation: 31
I'm trying to rewrite Perl script to Java. There is a line in this script with pack function:
my $key = '0rdR-0PrdK';
$key = pack("H*", $key);
The method i use in java is:
private static byte[] hexToBytes(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
it works correctly on hex strings, but it doesnt on non-hex strings
on the left bytes received in java, on the right from perl '0rdR-0PrdK'
-1 11
-49 -37
-16 -48
-17 -101
-49 -44
Have any of you had such a problem? How to solve it?
Upvotes: 2
Views: 202
Reputation: 31
pack("H*", '0rdR-0PrdK')
produces garbage.
Thats true, but this garbage were used as secret key in encryption algorithm. It was possible to decrypt when you used the same garbage.
I was really pressed on time so i did it this way:
private static final String[] possibleChars = {"0`", "`0", "0~", "~0", "0!", "!0", "0@", "@0", "0#", "#0", "0$", "$0", "0%", "%0", "0^", "^0",
"0&", "&0", "0*", "*0", "0(", "(0", "0)", ")0", "0-", "-0", "0_", "_0", "0=", "=0", "0+", "+0", "0[", "[0", "0{", "{0",
"0]", "]0", "0}", "}0", "0\\", "\\0", "0|", "|0", "0;", ";0", "0:", ":0", "0'", "'0", "0\"", "\"0", "0,", ",0", "0<",
"<0", "0.", ".0", "0>", ">0", "0/", "/0", "0?", "?0", "0a", "a0", "0b", "b0", "0c", "c0", "0d", "d0", "0e", "e0", "0f",
"f0", "0g", "g0", "0h", "h0", "0i", "i0", "0j", "j0", "0k", "k0", "0l", "l0", "0m", "m0", "0n", "n0", "0o", "o0", "0p",
"p0", "0q", "q0", "0r", "r0", "0s", "s0", "0t", "t0", "0u", "u0", "0v", "v0", "0w", "w0", "0x", "x0", "0y", "y0", "0z",
"z0", "00", "00", "01", "10", "02", "20", "03", "30", "04", "40", "05", "50", "06", "60", "07", "70", "08", "80", "09", "90"};
private static final String[] base64codes = {"AA==", "AA==", "Dg==", "4A==", "AQ==", "EA==", "AA==", "AA==", "Aw==", "MA==", "BA==",
"QA==", "BQ==", "UA==", "Dg==", "4A==", "Bg==", "YA==", "Cg==", "oA==", "CA==", "gA==", "CQ==", "kA==", "DQ==", "0A==",
"Dw==", "8A==", "DQ==", "0A==", "Cw==", "sA==", "Cw==", "sA==", "Cw==", "sA==", "DQ==", "0A==", "DQ==", "0A==", "DA==",
"wA==", "DA==", "wA==", "Cw==", "sA==", "Cg==", "oA==", "Bw==", "cA==", "Ag==", "IA==", "DA==", "wA==", "DA==", "wA==",
"Dg==", "4A==", "Dg==", "4A==", "Dw==", "8A==", "Dw==", "8A==", "Cg==", "oA==", "Cw==", "sA==", "DA==", "wA==", "DQ==",
"0A==", "Dg==", "4A==", "Dw==", "8A==", "AA==", "AA==", "AQ==", "EA==", "Ag==", "IA==", "Aw==", "MA==", "BA==", "QA==",
"BQ==", "UA==", "Bg==", "YA==", "Bw==", "cA==", "CA==", "gA==", "CQ==", "kA==", "Cg==", "oA==", "Cw==", "sA==", "DA==",
"wA==", "DQ==", "0A==", "Dg==", "4A==", "Dw==", "8A==", "AA==", "AA==", "AQ==", "EA==", "Ag==", "IA==", "Aw==", "MA==",
"AA==", "AA==", "AQ==", "EA==", "Ag==", "IA==", "Aw==", "MA==", "BA==", "QA==", "BQ==", "UA==", "Bg==", "YA==", "Bw==",
"cA==", "CA==", "gA==", "CQ==", "kA=="};
private static void initializeHashMap() {
for (int i = 0; i < possibleChars.length; i++) {
hashMap.put(possibleChars[i], base64codes[i]);
}
}
public static byte[] h16pack(String s) {
String str = s.toLowerCase();
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) (Base64.decode(hashMap.get(str.charAt(i) + "0"))[0]
+ Base64.decode(hashMap.get("0" + str.charAt(i + 1)))[0]);
}
return data;
}
not elegant, but it works
Upvotes: 1
Reputation: 386331
pack("H*", '0rdR-0PrdK')
produces garbage.
$ perl -M5.014 -e'
my $encoded = pack "H*", $ARGV[0];
my $decoded = unpack "H*", $encoded;
say $decoded;
say $decoded eq $ARGV[0] ? "ok" : "ERROR";
' 0rdR-0PrdK
0bdbd09bd4
ERROR
It's impossible to get 0rdR-0PrdK
from the the output of pack("H*", 0rdR-0PrdK")
.
Someone meant to use unpack "H*"
but accidentally used pack "H*"
.
# bytes -> hex
$ perl -M5.014 -e'say unpack "H*", $ARGV[0]' 0rdR-0PrdK
307264522d305072644b
# hex -> bytes
$ perl -M5.014 -e'say pack "H*", $ARGV[0]' \
"$( perl -M5.014 -e'say unpack "H*", $ARGV[0]' 0rdR-0PrdK )"
0rdR-0PrdK
You should fix that instead of trying to work around the bug.
The bytes you want can be obtained using the following:
$ perl -M5.014 -e'say for unpack "c*", pack "H*", $ARGV[0]' 0rdR-0PrdK
11
-37
-48
-101
-44
The following will provide a string you can pass to hexToBytes
to obtain the same result:
$ perl -M5.014 -e'say for unpack "H*", pack "H*", $ARGV[0]' 0rdR-0PrdK
0bdbd09bd4
Upvotes: 2