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

C语言中比特与无符号字符数组比较及SHA256部分碰撞测试技术问询

解决SHA256哈希前24比特与十六进制参数的比较问题

我来帮你搞定这个C语言里的比特级比较需求,结合你的场景(检测SHA256哈希前24比特是否匹配2612c7),咱们一步步实现:

核心思路

要完成这个比较,需要分三个关键步骤:

  • 把命令行传入的十六进制字符串(argv[1])转换成对应的24比特数值
  • 从SHA256哈希结果(buffer)中提取前24比特并转换成相同格式的数值
  • 直接比较两个数值是否相等,相等即找到部分碰撞

具体实现代码

结合OpenSSL的EVP库,给你一个完整的可运行代码片段:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <24-bit-hex-prefix>\n", argv[0]);
        return EXIT_FAILURE;
    }

    // 步骤1:解析命令行参数为24比特目标值
    uint32_t target_prefix = 0;
    if (sscanf(argv[1], "%x", &target_prefix) != 1) {
        fprintf(stderr, "Invalid hexadecimal input\n");
        return EXIT_FAILURE;
    }
    // 掩码确保只保留低24比特(防止输入超过6位十六进制的情况)
    target_prefix &= 0xFFFFFF;

    // 初始化SHA256上下文
    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
    if (!mdctx) {
        fprintf(stderr, "Failed to create EVP context\n");
        return EXIT_FAILURE;
    }
    if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1) {
        fprintf(stderr, "Failed to initialize SHA256\n");
        EVP_MD_CTX_free(mdctx);
        return EXIT_FAILURE;
    }

    // 随机字节缓冲区(可根据需求调整大小)
    unsigned char random_data[32];
    unsigned char hash_buffer[EVP_MAX_MD_SIZE];
    unsigned int hash_len;

    printf("Searching for SHA256 prefix matching: %s\n", argv[1]);

    // 循环生成随机数据并检测哈希前缀
    while (1) {
        // 生成高质量随机数据(比rand()更安全)
        if (RAND_bytes(random_data, sizeof(random_data)) != 1) {
            fprintf(stderr, "Failed to generate random data\n");
            break;
        }

        // 计算SHA256哈希
        if (EVP_DigestUpdate(mdctx, random_data, sizeof(random_data)) != 1) {
            fprintf(stderr, "Failed to update digest\n");
            break;
        }
        if (EVP_DigestFinal_ex(mdctx, hash_buffer, &hash_len) != 1) {
            fprintf(stderr, "Failed to finalize digest\n");
            break;
        }
        // 重置上下文,准备下一次哈希计算
        EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);

        // 步骤2:提取哈希的前24比特(SHA256输出是大端序,按字节拼接)
        uint32_t hash_prefix = ((uint32_t)hash_buffer[0] << 16) | 
                               ((uint32_t)hash_buffer[1] << 8) | 
                               hash_buffer[2];

        // 步骤3:比较前缀
        if (hash_prefix == target_prefix) {
            printf("Found match!\n");
            printf("Random data: ");
            for (int i = 0; i < sizeof(random_data); i++) {
                printf("%02x", random_data[i]);
            }
            printf("\nSHA256 hash: ");
            for (int i = 0; i < hash_len; i++) {
                printf("%02x", hash_buffer[i]);
            }
            printf("\n");
            break;
        }
    }

    EVP_MD_CTX_free(mdctx);
    return EXIT_SUCCESS;
}

关键细节解释

  1. 十六进制参数解析:
    • 用sscanf("%x", ...)把字符串转成32位整数,再用0xFFFFFF掩码确保只保留低24比特,避免输入过长的十六进制字符串导致错误。
  2. 哈希前缀提取:
    • SHA256的输出是大端字节序,所以哈希的第一个字节是最高8位,第二个是中间8位,第三个是最低8位。通过左移操作把这三个字节拼接成一个32位整数,刚好对应前24比特的数值。
  3. 随机数据生成:
    • 用OpenSSL的RAND_bytes生成随机数据,比标准库的rand()安全性更高,更适合碰撞测试场景。
  4. 上下文重置:
    • 每次计算哈希后,需要用EVP_DigestInit_ex重置上下文,才能重新计算下一个随机数据的哈希。

编译与运行

编译时需要链接OpenSSL库:

gcc -o sha256 sha256_collision.c -lcrypto

运行时传入目标前缀:

./sha256 2612c7

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:30:50