给出c++实现sha_1算法的完整代码
时间: 2024-10-03 16:01:47 浏览: 25
SHA-1是一种哈希算法,可以将数据(通常是消息或文件)生成一个唯一的40个字符长度的哈希值,常用于数字签名和数据完整性验证等领域。以下是一个c++实现SHA-1算法的完整代码:
```
#include <iostream>
#include <cstring>
using namespace std;
const int kBlockSize = 64;
class SHA1 {
public:
SHA1();
void Update(const unsigned char* data, size_t length);
void Final(unsigned char* hash);
void Reset();
private:
void ProcessBlock(const unsigned char* data);
void PadBlock();
void ResetState();
uint32_t state_;
uint32_t count_;
uint8_t buffer_[kBlockSize];
int buffer_size_;
};
// 工具函数:将4个字节的数据按大端序转换为一个32位无符号整数
inline uint32_t ByteToWord(const uint8_t* bytes) {
return ((uint32_t)bytes << 24) |
((uint32_t)bytes << 16) |
((uint32_t)bytes << 8) |
((uint32_t)bytes);
}
// 工具函数:将一个32位无符号整数按大端序转换为4个字节
inline void WordToByte(uint32_t word, uint8_t* bytes) {
bytes[0] = (word >> 24) & 0xff;
bytes = (word >> 16) & 0xff;
bytes = (word >> 8) & 0xff;
bytes = word & 0xff;
}
SHA1::SHA1() {
ResetState();
Reset();
}
void SHA1::ResetState() {
state_ = 0x67452301;
state_ = 0xefcdab89;
state_ = 0x98badcfe;
state_ = 0x10325476;
state_ = 0xc3d2e1f0;
}
void SHA1::Reset() {
count_ = count_ = 0;
buffer_size_ = 0;
}
void SHA1::Update(const unsigned char* data, size_t length) {
while (length > 0) {
size_t available_space_in_buffer = kBlockSize - buffer_size_;
size_t bytes_to_copy = min(length, available_space_in_buffer);
memcpy(buffer_ + buffer_size_, data, bytes_to_copy);
data += bytes_to_copy;
length -= bytes_to_copy;
buffer_size_ += bytes_to_copy;
if (buffer_size_ == kBlockSize) {
ProcessBlock(buffer_);
buffer_size_ = 0;
}
}
}
void SHA1::Final(unsigned char* hash) {
PadBlock();
uint8_t result[20];
for (int i = 0; i < 5; i++) {
WordToByte(state_[i], result + i * 4);
}
memcpy(hash, result, 20);
Reset();
}
void SHA1::ProcessBlock(const unsigned char* data) {
uint32_t w[80];
for (int i = 0; i < 16; i++) {
w[i] = ByteToWord(data + i * 4);
}
for (int i = 16; i < 80; i++) {
w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
w[i] = (w[i] << 1) | (w[i] >> 31);
}
uint32_t a = state_;
uint32_t b = state_[1];
uint32_t c = state_;
uint32_t d = state_;
uint32_t e = state_;
for (int i = 0; i < 80; i++) {
uint32_t f, k;
if (i < 20) {
f = (b & c) | ((~b) & d);
k = 0x5a827999;
} else if (i < 40) {
f = b ^ c ^ d;
k = 0x6ed9eba1;
} else if (i < 60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8f1bbcdc;
} else {
f = b ^ c ^ d;
k = 0xca62c1d6;
}
uint32_t temp = (a << 5) | (a >> 27);
temp += f + e + k + w[i];
e = d;
d = c;
c = (b << 30) | (b >> 2);
b = a;
a = temp;
}
state_ += a;
state_[1] += b;
state_ += c;
state_ += d;
state_[4] += e;
}
void SHA1::PadBlock() {
uint64_t bit_count = count_ * 8 + count_;
int padding_size_in_bytes =
bit_count % kBlockSize >= kBlockSize - 8 ?
2 * kBlockSize - bit_count % kBlockSize :
kBlockSize - bit_count % kBlockSize;
uint8_t padding[2 * kBlockSize];
memset(padding, 0, padding_size_in_bytes);
padding = 0x80;
uint64_t bit_count_be = htobe64(bit_count);
memcpy(padding + padding_size_in_bytes, &bit_count_be, sizeof(bit_count_be));
Update(padding, padding_size_in_bytes + sizeof(bit_count_be));
}
int main() {
string message = "Hello, world!";
unsigned char hash[20];
SHA1 sha1;
sha1.Update((const unsigned char*)message.c_str(), message.size());
sha1.Final(hash);
cout << "The SHA-1 hash of \"" << message << "\" is: ";
for (int i = 0; i < 20; i++) {
printf("%02x", hash[i]);
}
cout << endl;
return 0;
}
```
阅读全文