SHA-1哈希如何在Android上的Java上运行

时间:2012-11-08 16:54:45

标签: java android hash sha1

我搜索了如何散列设备标识符,并偶然发现了以下代码。

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

  1. 为什么我需要urlEncode设备ID?
  2. 为什么我需要对字节进行哈希处理,我不能在字符串上执行该操作吗?
  3. 为什么我需要将其转换为BigInteger?
  4. 为什么我需要移位来获取带有散列id的String?
  5. 任何人都可以解释一下一行一行吗?我希望这会帮助其他人理解这个在博客和论坛中传播的片段。

    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;
    

4 个答案:

答案 0 :(得分:3)

为什么我需要urlEncode设备ID?

  

为什么我需要对字节进行散列,我不能在字符串上执行该操作吗?

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

他们提供的代码行使用默认编码,这有点脆弱。我更愿意看到像

这样的东西
byte bytes[] = digest.digest(deviceId.getBytes(Charset.forName("UTF-8")));
  

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

这是为了方便使用,以帮助转换为十六进制表示。

  

为什么我需要移位来获取带有散列id的String?

正在使用的格式字符串是%0Nx,这会导致字符串被零填充为N个字符。由于以十六进制表示一个字节需要两个字符,Nbytes*2,结果为bytes << 1

我真的不明白为什么你不仅仅包括Guava for Android并使用Hashing builder

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

它是一行,不会抛出已检查的异常。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

它被转换为BigInteger,因此可以一致地格式化每个字节有两个十六进制数字。 (这就是左移时长度乘以2的原因。)

基本上,您所有问题的答案都是:以便您获得可靠,可重复的结果,即使在不同的平台上也是如此

答案 3 :(得分:0)

您也可以使用此代码:

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

        }