java中具有非十六进制字符的等效perl包(“h*”)

fivyi3re  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(312)

我正在尝试将perl脚本重写为java。此脚本中有一行包含pack函数:

my $key = '0rdR-0PrdK';
$key = pack("H*", $key);

我在java中使用的方法是:

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

它在十六进制字符串上正常工作,但在非十六进制字符串上不工作
左边是java接收的字节,右边是perl'0rdr-0prdk'

-1      11
-49     -37
-16     -48
-17     -101
-49     -44

你们有谁有这样的问题吗?如何解决?

uz75evzq

uz75evzq1#

pack("H*", '0rdR-0PrdK') 产生垃圾。

$ 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

这是不可能的 0rdR-0PrdK 从输出 pack("H*", 0rdR-0PrdK") .
有人想用 unpack "H*" 但不小心用了 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

你应该解决这个问题,而不是试图解决这个问题。
可以使用以下方法获得所需的字节:

$ perl -M5.014 -e'say for unpack "c*", pack "H*", $ARGV[0]' 0rdR-0PrdK
11
-37
-48
-101
-44

下面将提供一个可以传递到的字符串 hexToBytes 要获得相同的结果:

$ perl -M5.014 -e'say for unpack "H*", pack "H*", $ARGV[0]' 0rdR-0PrdK
0bdbd09bd4
c9x0cxw0

c9x0cxw02#

pack("H*", '0rdR-0PrdK') 产生垃圾。
没错,但在加密算法中,这些垃圾被用作密钥。当你使用相同的垃圾时,解密是可能的。
我真的时间紧迫,所以我这样做:
我在perl中找到了每个字符的压缩(h*…)值
用base64编码
在java中解码硬编码值

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

不是很优雅,但很管用

相关问题