3

私は携帯電話を扱っており、毎日 MEID 番号を扱っています。したがって、MEID (長さ 14 の 16 進数) から疑似 ESN (長さ 8 の 16 進数) 計算機をオンラインで検索する代わりに、独自のプログラムを作成できると考えました。MEID から pESN を取得する方法は、理論的にはかなり単純です。たとえば、MEID 0xA0000000002329 の場合、pESN を作成するには、MEID に SHA-1 を適用する必要があります。A0000000002329 の SHA-1 は、e3be267a2cd5c861f3c7ea4224df829a3551f1ab を提供します。この結果の最後の 6 つの 16 進数を取得し、それを 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 が e3be267a2cd5c861f3c7ea4224df829a3551f1ab の代わりに a89b611b421f57705bd013297ce3fc835f706ab0 を与えることです。ここで何が間違っていますか??

誰かが私にヒントをくれました。「コツは、MEID を表す文字列ではなく、MEID を表す数値に SHA-1 を適用することです。バイト単位で処理する必要があるため、2 つの 16 進数を指定する必要があります。一度に (2 つの 16 進数で 1 バイトを構成するため)、それらが ASCII 文字ではなく数値として解釈されることを確認してください。" . これが正しい場合、文字列を 16 進数に変更してからバイトに変更し、SHA1 が正しい結果を返すにはどうすればよいですか?

4

3 に答える 3

3

ライブラリがない場合は、次の例に従うことができます。

Java では、16 進文字列をバイト [] に変換するにはどうすればよいですか?

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

これも提供する1つのライブラリ(たくさんあると思います)は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

文字列から 16 進数の場合:

public String StrToHex(String arg) {

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

16 進数からバイトへ:

以下のコードは「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

次の 2 つの方法を使用できます。

    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 に答える