【问题标题】:How SHA-1 hashing works on Java on AndroidSHA-1 哈希如何在 Android 上的 Java 上工作
【发布时间】:2012-11-08 16:54:45
【问题描述】:

我四处搜索如何对设备标识符进行哈希处理并偶然发现了以下代码。

我真的不明白它在做什么。

  1. 为什么需要对设备ID进行urlEncode?​​li>
  2. 为什么我需要对字节进行哈希处理,难道我不能只对字符串进行哈希处理吗?
  3. 为什么需要将其转换为 BigInteger?
  4. 为什么我需要移动位来获得带有散列 id 的字符串?

谁能逐行解释发生了什么?我希望这也能帮助其他人理解这个在博客和论坛中传播的 sn-p。

String hashedId = "";

String deviceId = urlEncode(Secure.getString(context.getContentResolver(), Secure.ANDROID_ID));

try {
    MessageDigest digest = MessageDigest.getInstance("SHA-1");

    byte bytes[] = digest.digest(deviceId.getBytes());

    BigInteger b = new BigInteger(1, bytes);
    hashedId = String.format("%0" + (bytes.length << 1) + "x", b);

} catch (NoSuchAlgorithmException e) {
    //ignored
}

return hashedId;

【问题讨论】:

  • 您对所使用的散列技术有什么不了解的地方?
  • 我不明白你为什么需要对 android id 进行 urlEncode。我不了解有关 MessageDigest 的部分。那是什么?我可以传递任何字符串吗?为什么不消化字符串?为什么它必须消化字符串字节?为什么我得到一个字节数组? BigInteger 部分是怎么回事?位移位?为什么需要这样做。
  • 这是一个非常明确的问题,但我自己也无法回答,因为我不知道为什么每一行都这样写。我自己盲目地使用了这段代码 sn-p 并没有真正理解每一行的作用。
  • 我不能理解的主要是位移和 String.format 的东西。我不明白为什么会这样。

标签: java android hash sha1


【解决方案1】:

为什么我需要对设备 ID 进行 urlEncode 编码?

为什么我需要对字节进行哈希处理,我不能只在字符串上这样做吗?

包括 SHA-1 在内的大多数哈希算法都将二进制数据作为输入(即字节)。字符串本身没有特定的二进制表示;它会根据编码而变化。

他们提供的代码行使用的是默认编码,有点脆弱。我希望看到类似

byte bytes[] = digest.digest(deviceId.getBytes(Charset.forName("UTF-8")));

为什么需要将其转换为 BigInteger ?

这是为了方便转换为十六进制表示而使用的。

为什么我需要移位来获得带有散列 id 的字符串?

使用的格式字符串是%0Nx,这会导致字符串被零填充到N 字符。因为十六进制表示一个字节需要两个字符,所以N就是bytes*2,结果就是bytes &lt;&lt; 1。

我真的不明白你为什么不只包含Guava for Android 并使用Hashing builder:

String hash = Hashing.sha1().hashString(deviceId, Charsets.UTF_8).toString();

只有一行,不会抛出检查异常。

【讨论】:

    【解决方案2】:

    关于位移:左移1相当于乘以2。字符串中的每个字节由2个十六进制字符表示,因此生成的字符串将是哈希中字节数的两倍。

    这将创建一个类似于%032x 的格式字符串,它将一个整数值打印为一个用零填充的 32 个字符的字符串。

    【讨论】:

      【解决方案3】:

      您需要散列字节而不是字符串,以便散列 字符数据 而不是 String 对象,这对于给定的序列可能具有不可预测的内部状态字符。

      它已转换为 BigInteger,因此它可以一致地格式化为每字节两个十六进制数字。 (这就是为什么用左移将长度乘以 2。)

      基本上,您所有问题的答案都是:这样您即使在不同的平台上也能获得可靠、可重复的结果。

      【讨论】:

        【解决方案4】:

        您也可以使用此代码:

                 public class sha1Calculate {
        
                public static void main(String[] args)throws Exception
                {
                     File file = new File("D:\\Android Links.txt");
                    String outputTxt= "";
                    String hashcode = null;
        
                    try {
        
                        FileInputStream input = new FileInputStream(file);
        
                        ByteArrayOutputStream output = new ByteArrayOutputStream ();
                        byte [] buffer = new byte [65536];
                        int l;
        
                        while ((l = input.read (buffer)) > 0)
                            output.write (buffer, 0, l);
        
                        input.close ();
                        output.close ();
        
                        byte [] data = output.toByteArray ();
        
        
                            MessageDigest digest = MessageDigest.getInstance( "SHA-1" ); 
        
                        byte[] bytes = data;
        
                        digest.update(bytes, 0, bytes.length);
                        bytes = digest.digest();
        
                        StringBuilder sb = new StringBuilder();
        
                        for( byte b : bytes )
                        {
                            sb.append( String.format("%02X", b) );
                        }
        
                            System.out.println("Digest(in hex format):: " + sb.toString());
        
        
                    }catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        
                }
        

        【讨论】:

          猜你喜欢
          • 2017-02-26
          • 1970-01-01
          • 2017-08-19
          • 2011-10-14
          • 1970-01-01
          • 2016-02-03
          • 2014-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多