SHA-1(安全哈希算法1)是一种加密哈希函数,它接受一个输入并生成一个160位(20字节)的哈希值,通常表示为一个40位的十六进制数。
SHA1的特点
- 输入与输出:SHA-1可以接受几乎任意大小的输入,并输出固定长度的160位哈希值。
- 确定性:对于相同的输入,SHA-1总是生成相同的输出哈希值。
- 用途:广泛用于数据完整性验证和数字签名等领域。
整体流程
对输入的数据进行预处理,然后初始化变量、对每一个数据块进行循环压缩、更新哈希值、以及最终生成160位的哈希值。
消息预处理
将输入的消息进行填充,使其长度变为512位的倍数。填充方法是先在消息后加上一个1,然后加上若干个0,知道消息的长度能够对512取余等于448位,最后加上一个64位的二进制数表示原始消息长度。然后将填充后的消息按512位进行分块。
初始化缓冲区变量
设置5个32位的初始变量:H0, H1, H2, H3, H4,初始值分别为:
H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0
对每一个512位块进行处理
消息扩展
将512位的块分成16个32位的字(W0,W1,…,W15),然后通过位操作扩展生成新的64个32位的字,一共80个字(W0,W1,…,W79)。
初始化变量
将A, B, C, D, E
分别设置为当前的H0, H1, H2, H3, H4
80轮的压缩迭代
进行80轮循环,每轮使用不同的常数K和非线性函数f,来混合当前块的字和缓冲区变量。每一轮根据公式进行操作:
TEMP = (A << 5) + f(B, C, D) + E + W[i] + K
E = D
D = C
C = B << 30
B = A
A = TEMP
这里面A<<5表示A左移5位,f是根据当前轮数选择的非线性函数,K是不同轮数的常数,W[i]是扩展的消息字。
完成80轮之后,将A, B, C, D, E
的结果加到H0, H1, H2, H3, H4
中
H0 = H0 + A
H1 = H1 + B
H2 = H2 + C
H3 = H3 + D
H4 = H4 + E
输出哈希值
处理完毕后,将H0, H1, H2, H3, H4
连接在一起,得到一个160位(20字节)的最终哈希值。
Python调用
import hashlib
data = "Bileton"
sha1 = hashlib.sha1()
sha1.update(data.encode("utf-8"))
data_sha1 = sha1.hexdigest()
print(data_sha1)
>>> ab345d2ef3e3a48433207b746c9cb3a49b473e3a
Java调用
try {
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
String data = "Bileton";
byte[] data_sha1 = sha1.digest(data.getBytes());
System.out.println(HexFormat.of().formatHex(data_sha1));
// ab345d2ef3e3a48433207b746c9cb3a49b473e3a
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
Android Studio
String data = "Bileton";
try {
MessageDigest sha1 = MessageDigest.getInstance("sha-1");
byte[] data_sha1 = sha1.digest();
String sha1_string =bytesToHex(data_sha1); // 这里的bytesToHex看我的Hex编码文章
Toast.makeText(MainActivity.this,sha1_string,Toast.LENGTH_SHORT).show();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}