3

我每天都使用手机并处理 MEID 号码。因此,与其在线搜索 MEID(长度为 14 的十六进制数)到伪 ESN(长度为 8 的十六进制数)计算器,我想我可以制作自己的程序。从 MEID 获取 pESN 的方法在理论上相当简单。例如,给定 MEID 0xA0000000002329,要制作 pESN,需要将 SHA-1 应用于 MEID。A0000000002329 上的 SHA-1 给出 e3be267a2cd5c861f3c7ea4224df829a3551f1ab。取此结果的最后 6 个十六进制数字,并将其附加到 0x80 - 结果是 0x8051F1AB。

现在这是我到目前为止的代码:

public void sha1() throws NoSuchAlgorithmException {

    String hexMEID = "A0000000002329";

    MessageDigest mDigest = MessageDigest.getInstance("SHA1");      

    byte[] result = mDigest.digest(hexMEID.getBytes());
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < result.length; i++) {
        sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
    }

    System.out.println(sb.toString());
}  

问题在于,使用这种方法,A0000000002329 上的 SHA-1 会给出 a89b611b421f57705bd013297ce3fc835f706ab0 而不是 e3be267a2cd5c861f3c7ea4224df829a3551f1ab。我在这里做错了什么?

有人给了我一个提示,“诀窍是将 SHA-1 应用于代表 MEID 的数字,而不是代表 MEID 的字符串。您需要逐字节处理它,因此您必须给它两个十六进制数字一次(因为两个十六进制数字组成一个字节)并确保它们被解释为数字而不是 ASCII 字符”。如果这是真的,那么我如何将我的字符串更改为十六进制,然后再更改为字节,以便 SHA1 可以给我正确的结果???

4

3 回答 3

3

如果没有库,您可以按照此处的示例进行操作:

在 Java 中,如何将十六进制字符串转换为字节 []?

 byte[] b = new BigInteger(s,16).toByteArray();

一个也提供此功能的库(我敢肯定有很多)是 POJava:

<dependency>
    <groupId>org.pojava</groupId>
    <artifactId>pojava</artifactId>
    <version>2.8.1</version>
</dependency>


 byte[] hexMEIDBytes=EncodingTool.hexDecode(hexMEID);

[编辑] ==============

根据您的后续问题,这是一个更完整的示例:

    byte[] hexMEIDBytes = EncodingTool.hexDecode(hexMEID);
    byte[] hash = HashingTool.hash(hexMEIDBytes, HashingAlgorithm.SHA);
    String pESN="0x80" + EncodingTool.hexEncode(hash).substring(34).toUpperCase();
    // a hexMEID value of "A0000000002329" results in a pESN value of "0x8051F1AB"
于 2012-08-06T04:24:04.363 回答
2

对于字符串到十六进制:

public String StrToHex(String arg) {

    return String.format("%040x", new BigInteger(arg.getBytes(//Your Charset//)));
}

对于十六进制到字节:

下面的代码不适用于“0”。

public byte[] hexStrToByteArray(String s) {
    int leng = s.length();
    byte[] data = new byte[leng / 2];
    for (int i = 0; i < leng; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}
于 2012-08-06T04:40:10.183 回答
1

您可以使用以下两种方法

    public static synchronized String bytesToHex(byte [] buf){
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10){
                strbuf.append("0");
            }
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }

    public synchronized static byte[] hexToBytes(String hexString) {
         byte[] b = new BigInteger(hexString,16).toByteArray();     
         return b;
    }
于 2012-08-06T04:38:42.220 回答