我搜索了如何散列设备标识符,并偶然发现了以下代码。
我真的不明白它在做什么。
任何人都可以解释一下一行一行吗?我希望这会帮助其他人理解这个在博客和论坛中传播的片段。
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;
答案 0 :(得分:3)
为什么我需要urlEncode设备ID?
为什么我需要对字节进行散列,我不能在字符串上执行该操作吗?
大多数散列算法(包括SHA-1)都将二进制数据作为输入(即字节)。字符串本身没有特定的二进制表示;它会根据编码而改变。
他们提供的代码行使用默认编码,这有点脆弱。我更愿意看到像
这样的东西byte bytes[] = digest.digest(deviceId.getBytes(Charset.forName("UTF-8")));
为什么我需要将其转换为BigInteger?
这是为了方便使用,以帮助转换为十六进制表示。
为什么我需要移位来获取带有散列id的String?
正在使用的格式字符串是%0Nx
,这会导致字符串被零填充为N
个字符。由于以十六进制表示一个字节需要两个字符,N
为bytes*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();
}
}