来自C函数的哈希值 [英] Hash value from C function

查看:111
本文介绍了来自C函数的哈希值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,希望您能帮助我.

I have a problem and hope you can help me.

我有一个用C编写的函数,该函数返回哈希值.我的 令人头疼的是,当我从其他工具执行程序时,这需要花费大量时间才能运行,这可能是因为在函数内部运行了一个在SHA256中哈希值的命令,所以我想知道是否还有另一种方法可以执行此操作,也许是函数之类的东西.

I have a function written in C that returns hash a value. My headache is when I execute the program from another tool it takes a lot of time to run, probably because inside my function I run a command that hashes my value in SHA256, so I would like to know if there is another way to do it, maybe a function or something like that.

这就是我所拥有的:

const char *EncryptSHA256 (char *Arg1) {  
    char command[128];
    char result[512];

    //I want to replace from here
    snprintf(command, sizeof command, "echo -n %s | sha256sum | cut -c1-64",Arg1);  

    FILE *fpipe;

    if (0 == (fpipe = (FILE*)popen(command, "r"))) {
        perror("popen() failed.");
        exit(1);
    }

    fread(result, 1, 512, fpipe);

    pclose(fpipe);
    const char *sha256 = &result[0];
    //to here

    return sha256;
}  

推荐答案

您的代码具有未定义的行为,因为您返回了指向result(具有自动存储功能的本地数组)的指针.调用者从此数组读取具有未定义的行为.

Your code has undefined behavior because you return a pointer to result, a local array with automatic storage. Reading from this array by the caller has undefined behavior.

您至少应该将result设为静态,以便在EncryptSHA256返回到其调用方之后其内容仍然可读.

You should at least make result static so its contents remain readable after EncryptSHA256 returns to its caller.

关于方法的低效率,这是SHA256的公共领域实现,您可以在程序内直接使用它:

Regarding the inefficiency of the method, here is a public domain implementation of SHA256 that you can use directly inside your program:

/* public domain sha256 implementation based on fips180-3 */

#include <stddef.h>
#include <stdint.h>
#include <string.h>

/* Public API */

struct sha256 {
    uint64_t len;    /* processed message length */
    uint32_t h[8];   /* hash state */
    uint8_t buf[64]; /* message block buffer */
};

/* reset state */
void sha256_init(struct sha256 *s);
/* process message */
void sha256_update(struct sha256 *s, const void *m, size_t len);
/* get message digest */
/* state is ruined after sum, keep a copy if multiple sum is needed */
/* part of the message might be left in s, zero it if secrecy is needed */
void sha256_sum(struct sha256 *s, uint8_t md[32]);

/* Implementation */

static uint32_t ror(uint32_t n, int k) {
    return (n >> k) | (n << (32 - k));
}
#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
#define Maj(x,y,z) ((x & y) | (z & (x | y)))
#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))
#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))
#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))
#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))

static const uint32_t K[64] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

static void processblock(struct sha256 *s, const uint8_t *buf) {
    uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
    int i;

    for (i = 0; i < 16; i++) {
        W[i]  = (uint32_t)buf[4 * i + 0] << 24;
        W[i] |= (uint32_t)buf[4 * i + 1] << 16;
        W[i] |= (uint32_t)buf[4 * i + 2] << 8;
        W[i] |= buf[4 * i + 3];
    }
    for (; i < 64; i++)
        W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
    a = s->h[0];
    b = s->h[1];
    c = s->h[2];
    d = s->h[3];
    e = s->h[4];
    f = s->h[5];
    g = s->h[6];
    h = s->h[7];
#define ROUND(a,b,c,d,e,f,g,h,i) \
        t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; \
        t2 = S0(a) + Maj(a,b,c); \
        d += t1; \
        h = t1 + t2;
    for (i = 0; i < 64; ) {
        ROUND(a, b, c, d, e, f, g, h, i); i++;
        ROUND(h, a, b, c, d, e, f, g, i); i++;
        ROUND(g, h, a, b, c, d, e, f, i); i++;
        ROUND(f, g, h, a, b, c, d, e, i); i++;
        ROUND(e, f, g, h, a, b, c, d, i); i++;
        ROUND(d, e, f, g, h, a, b, c, i); i++;
        ROUND(c, d, e, f, g, h, a, b, i); i++;
        ROUND(b, c, d, e, f, g, h, a, i); i++;
    }
#undef ROUND
    s->h[0] += a;
    s->h[1] += b;
    s->h[2] += c;
    s->h[3] += d;
    s->h[4] += e;
    s->h[5] += f;
    s->h[6] += g;
    s->h[7] += h;
}

static void pad(struct sha256 *s) {
    unsigned r = s->len % 64;

    s->buf[r++] = 0x80;
    if (r > 56) {
        memset(s->buf + r, 0, 64 - r);
        r = 0;
        processblock(s, s->buf);
    }
    memset(s->buf + r, 0, 56 - r);
    s->len *= 8;
    s->buf[56] = s->len >> 56;
    s->buf[57] = s->len >> 48;
    s->buf[58] = s->len >> 40;
    s->buf[59] = s->len >> 32;
    s->buf[60] = s->len >> 24;
    s->buf[61] = s->len >> 16;
    s->buf[62] = s->len >> 8;
    s->buf[63] = s->len;
    processblock(s, s->buf);
}

void sha256_init(struct sha256 *s) {
    s->len = 0;
    s->h[0] = 0x6a09e667;
    s->h[1] = 0xbb67ae85;
    s->h[2] = 0x3c6ef372;
    s->h[3] = 0xa54ff53a;
    s->h[4] = 0x510e527f;
    s->h[5] = 0x9b05688c;
    s->h[6] = 0x1f83d9ab;
    s->h[7] = 0x5be0cd19;
}

void sha256_sum(struct sha256 *s, uint8_t md[20]) {
    int i;

    pad(s);
    for (i = 0; i < 8; i++) {
        md[4 * i + 0] = s->h[i] >> 24;
        md[4 * i + 1] = s->h[i] >> 16;
        md[4 * i + 2] = s->h[i] >> 8;
        md[4 * i + 3] = s->h[i];
    }
}

void sha256_update(struct sha256 *s, const void *m, unsigned long len) {
    const uint8_t *p = m;
    unsigned r = s->len % 64;

    s->len += len;
    if (r) {
        if (len < 64 - r) {
            memcpy(s->buf + r, p, len);
            return;
        }
        memcpy(s->buf + r, p, 64 - r);
        len -= 64 - r;
        p += 64 - r;
        processblock(s, s->buf);
    }
    for (; len >= 64; len -= 64, p += 64)
        processblock(s, p);
    memcpy(s->buf, p, len);
}

您将功能更改为此:

const char *EncryptSHA256(char *Arg1) {  
    struct sha256 s;
    unsigned char md[32];
    static char result[65];

    sha256_init(&s);
    sha256_update(&s, Arg1, strlen(Arg1));
    sha256_sum(&s, md);
    for (int i = 0; i < 32; i++) {
        sprintf(result + i * 2, "%02x", md[i]);
    }
    return result;
}

如果更方便,您也可以更改API以传递32个无符号字符的数组以获取二进制形式.

You could also change the API to pass an array of 32 unsigned characters to get the binary form if it is more convenient.

这篇关于来自C函数的哈希值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆