You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言SHA512摘要转整数及取模问题求助(附Python对比代码)

问题描述

我用SHA512生成消息摘要,想在C语言里把它转成512位整数后对某个数(比如7)取模。但用atoi或strtol转换时总是得到0,而Python里用int.from_bytes能正常实现。作为C语言新手,我需要解决这个转换问题,或者找到更高效的摘要取模方法。

我的代码如下:

C语言代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenSSL/sha.h>

int main() {
    unsigned char message[] = "hello world";
    unsigned char digest[SHA512_DIGEST_LENGTH]; // 注意:SHA512摘要长度为64字节,不是512
    SHA512(message, strlen((char *)message), digest);
    int integer_value = atoi((char *)digest);
    printf("The integer value of the message is %d\n", integer_value);
    return 0;
}

Python代码

import hashlib
import sys 

Message = "hello world"
integer_value = int.from_bytes(hashlib.sha512(Message.encode()).digest(), sys.byteorder)

取模示例(Python)

import hashlib
import sys 

Message = "hello world"
integer_value = int.from_bytes(hashlib.sha512(Message.encode()).digest(), sys.byteorder)
Modulo = integer_value % 7
问题原因

用atoi转换得到0的核心原因是:SHA512生成的digest是二进制字节数组,不是ASCII数字字符串。atoi仅能将"123"这类ASCII字符序列转为整数,而二进制字节中大概率包含非数字ASCII字符,甚至第一个字节就是0x00(字符串终止符),因此atoi会直接返回0。

解决方案

方法一:直接对摘要字节数组取模(高效推荐)

无需将整个512位摘要转为整数,利用模运算性质(a * 256 + b) % m = ((a % m) * 256 + b) % m,逐字节处理即可得到最终模结果,既高效又避免了超大整数的存储问题。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenSSL/sha.h>

int main() {
    unsigned char message[] = "hello world";
    unsigned char digest[SHA512_DIGEST_LENGTH];
    SHA512(message, strlen((char *)message), digest);

    const int mod = 7;
    unsigned long long result = 0; // 用足够大的类型存储中间结果,防止溢出

    // 与Python默认小端字节序对应,从最后一个字节开始遍历;若用大端序则从第一个字节开始
    for (int i = SHA512_DIGEST_LENGTH - 1; i >= 0; i--) {
        result = (result * 256 + digest[i]) % mod;
    }

    printf("Digest mod %d is %llu\n", mod, result);
    return 0;
}

方法二:转换为512位整数(仅作演示,不推荐)

C语言无原生512位整数类型,需借助大整数库(如OpenSSL的BIGNUM)实现。示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenSSL/sha.h>
#include <OpenSSL/bn.h>

int main() {
    unsigned char message[] = "hello world";
    unsigned char digest[SHA512_DIGEST_LENGTH];
    SHA512(message, strlen((char *)message), digest);

    // 初始化大整数
    BIGNUM *bn = BN_new();
    BN_bin2bn(digest, SHA512_DIGEST_LENGTH, bn);

    // 计算模7
    BIGNUM *mod = BN_new();
    BN_set_word(mod, 7);
    BIGNUM *result = BN_new();
    BN_mod(result, bn, mod, NULL);

    // 打印结果
    char *result_str = BN_bn2dec(result);
    printf("Digest mod 7 is %s\n", result_str);

    // 释放资源
    BN_free(bn);
    BN_free(mod);
    BN_free(result);
    OPENSSL_free(result_str);

    return 0;
}

编译时需链接OpenSSL库:gcc your_code.c -o output -lcrypto

说明
  • 方法一更高效,无需处理超大整数的存储与运算,适合绝大多数取模场景。
  • 注意字节序匹配:Python的int.from_bytes默认使用系统字节序(通常为小端),因此方法一中的循环顺序需对应调整。

内容的提问来源于stack exchange,提问作者hah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:47:43