sha1算法实现(收集网络中好的代码)

sha1算法实现(收集网络中好的代码)

  • sha1.cpp
// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "sha1.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define SHA1_BLOCK_SIZE 20
#define SHA1_DIGEST_SIZE 20
#define SHA1_BLOCK_SIZE 64

typedef unsigned char uint8; // 8位无符号整数类型

// 定义SHA-1上下文结构体
typedef struct {
    uint32_t state[5];           // 存储中间结果
    uint32_t count[2];           // 存储输入比特数
    unsigned char buffer[SHA1_BLOCK_SIZE];    // 输入缓冲区
} SHA1_CTX;
/* 常量表 */
static const uint8 PADDING[SHA1_BLOCK_SIZE] = {
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 初始化SHA-1上下文
void Sha1_Init(SHA1_CTX *ctx) {
    ctx->state[0] = 0x67452301;
    ctx->state[1] = 0xEFCDAB89;
    ctx->state[2] = 0x98BADCFE;
    ctx->state[3] = 0x10325476;
    ctx->state[4] = 0xC3D2E1F0;

    ctx->count[0] = ctx->count[1] = 0;
}

// 执行SHA-1转换
void Sha1_Transform(SHA1_CTX *ctx, const unsigned char *data) {
    uint32_t a, b, c, d, e, temp;
    uint32_t w[80];
    // 将block划分为16个32位字
    for (int i = 0; i < 16; i++) {
        w[i] = data[i * 4 + 0] << 24 |
                data[i * 4 + 1] << 16 |
                data[i * 4 + 2] << 8 |
                data[i * 4 + 3];
    }
    // 扩展消息块
    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);
    }

    // 初始化哈希值
    a = ctx->state[0];
    b = ctx->state[1];
    c = ctx->state[2];
    d = ctx->state[3];
    e = ctx->state[4];

    // 主循环
    for (int i = 0; i < 80; i++) {
        if (i < 20) {
            temp = ((b & c) | ((~b) & d)) + 0x5A827999;
        } else if (i < 40) {
            temp = (b ^ c ^ d) + 0x6ED9EBA1;
        } else if (i < 60) {
            temp = ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC;
        } else {
            temp = (b ^ c ^ d) + 0xCA62C1D6;
        }

        temp += ((a << 5) | (a >> 27)) + e + w[i];
        e = d;
        d = c;
        c = (b << 30) | (b >> 2);
        b = a;
        a = temp;
    }

    // 计算下一个消息块
    ctx->state[0] += a;
    ctx->state[1] += b;
    ctx->state[2] += c;
    ctx->state[3] += d;
    ctx->state[4] += e;
}

// 更新SHA-1上下文
void Sha1_Update(SHA1_CTX *ctx, const unsigned char *data, uint32_t len) {
    uint32_t i, index, partlen;

    index = (ctx->count[0] >> 3) & 0x3F;
    ctx->count[0] += len << 3;

    if (ctx->count[0] < (len << 3)) {
        ctx->count[1]++;
    }

    ctx->count[1] += (len >> 29);
    // 计算处理后的数据长度
    partlen = SHA1_BLOCK_SIZE - index;
    if (len >= partlen) {
        memcpy(&(ctx->buffer[index]), data, partlen);
        Sha1_Transform(ctx, ctx->buffer);

        for (i = partlen; i+SHA1_BLOCK_SIZE <= len; i += SHA1_BLOCK_SIZE) {
            Sha1_Transform(ctx, &(data[i]));
        }

        index = 0;
    } else {
        i = 0;
    }

    memcpy(&(ctx->buffer[index]), &(data[i]), len - i);
}

// 结束SHA-1计算,返回摘要结果
void Sha1_Final(unsigned char digest[SHA1_DIGEST_SIZE], SHA1_CTX *ctx) {
    uint32_t i,index, padlen;
    uint8_t  bits[8];

//    memcpy(bits, ctx->count, 8);
    // 数据长度填充方式和md5有区别,为大端方式填充
    for (i = 0; i < 8; i++)
    {
        bits[i] = (unsigned char)((ctx->count[(i >= 4 ? 0 : 1)]
                >> ((3 - (i & 3)) * 8)) & 255); /*   Endian   independent   */
    }
    index = (ctx->count[0] >> 3) & 0x3F;
    //计算需要填充的长度
    padlen = (index < 56) ? (56 - index) : (120 - index);
    // 数据填充
    Sha1_Update(ctx, PADDING, padlen);
    // 填充长度
    Sha1_Update(ctx, bits, 8);
    for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
        digest[i] = (unsigned char)((ctx->state[i>>2] >> ((3-(i & 3)) * 8)) & 0xFF);
    }

    // 清空敏感信息
    memset(ctx, 0, sizeof(*ctx));
}
void testsha1() {
    unsigned char digest[SHA1_DIGEST_SIZE];
    SHA1_CTX ctx;

    // 测试用例1
    const char *str1 = "123456";
    Sha1_Init(&ctx);
//    Sha1_Update1(&ctx, (const unsigned char *)str1, strlen(str1));
//    Sha1_Final1(&ctx ,digest);
    Sha1_Update(&ctx, (const unsigned char *)str1, strlen(str1));
    Sha1_Final(digest,&ctx);
    printf("SHA-1 hash for '%s': ", str1);

    for (int i = 0; i < SHA1_DIGEST_SIZE; i++) {
        printf("%02x", digest[i]);
    }
    printf("\n");
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值