gcc 生成散列时-pg和优化的奇怪行为

jgovgodb  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(151)

我决定编写一个程序来查找开头有一定数量的零的sha 3 -512散列。(就像hashcash一样)。它在我最初的测试中运行得很好,所以我决定用gprof分析它,看看是否能让它更快。在我用-pg编译并运行它之后,我想我应该去买一张乐透彩票。在第一个nonce上,我得到了一个有 *8个零 * 的哈希。然而,我又运行了一次,还是得到了一个开头有8个零的数字。事实上,在哈希中有许多可识别的模式。经过几次测试后,我发现只有当我用-pg * 和-O 1、-O2和-O3中的一个 * 编译时,才会发生这种情况。
这是程序

#include <tomcrypt.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#include <stdio.h>

unsigned char* randstring(size_t length) {
    srand(time(NULL));
    unsigned char* randomString = NULL;

    if (length) {
        randomString = malloc(sizeof(char) * (length));

        if (randomString) {
            for (int n = 0; n < length; n++) {
                int key = rand() % 255;
                randomString[n] = (unsigned char)key;
            }
        }
    }

    return randomString;
}

void find_nonce(int zeroes, int* nonce_ptr, unsigned char* returner) {
    unsigned char string[40];
    unsigned char* rand_string = randstring(30);

    memcpy(string, rand_string, 30);
    free(rand_string);
    //string is longer than rand_string because i need romm to put the nonce in

    int nonce = 0;

    int idx;

    if (register_hash(&sha3_512_desc) == -1) {
        printf("Error registering SHA3-512.\n");
        exit(1);
    }
    idx = find_hash("sha3-512");
    if (idx == -1) {
        printf("Invalid hash name!\n");
        exit(1);
    }

    int res_bool = false;
    unsigned char res[64];
    unsigned long res_size;
    char nonce_str[11];
    int nonce_len = 0;

    while (!res_bool) {
        //Put the nonce into a string
        sprintf(nonce_str, "%d", nonce);

        //Put the nonce string into the string as an unsigned char (hash_memory takes an unsigned char)
        for (int i = 0, j = 11;; ++i, ++j) {
            if (nonce_str[i] == '\0') {
                break;
            }
            string[j] = (unsigned char)nonce_str[i];
            nonce_len++;

        }

        //Hash it
        hash_memory(idx, string, 30+nonce_len, res, &res_size);

        nonce_len = 0;

        //Check if the string has a sufficient number of zeroes at the start
        res_bool = true;
        for (int i = 0; i < zeroes; i++) {
            if ((int)res[i] != 0) {
                res_bool = false;
                break;
            }
        }
        nonce++;

    }
    *nonce_ptr = nonce;

    for (int i = 0; i < 64; i++) {
        returner[i] = res[i];
    }
}

int main(int argc, char** argv) {
    //Getting command-line arguments
    int zeroes = atoi(argv[argc - 1]);
    
    int nonce;
    unsigned char hash[64];

    //Timing the execution
    clock_t start, end;
    double cpu_time_used;

    start = clock();

    find_nonce(zeroes, &nonce, hash);

    end = clock();
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;

    //Printing the output to the screen
    printf("Hash was ");
    for (int i = 0; i < 64; i++) {
        printf("%d ", (int)hash[i]);
    }
    printf("\nNonce to get the hash was %d\nIt took %f seconds to calculate\n", nonce, cpu_time_used);

    return 0;
}

下面是五个测试的输出示例:

Hash was 0 0 0 0 0 0 0 0 6 203 85 177 228 127 0 0 192 128 164 212 252 127 0 0 129 219 85 177 228 127 0 0 0 235 105 177 228 127 0 0 144 128 164 212 252 127 0 0 2 0 0 0 0 0 0 0 48 130 164 212 252 127 0 0 
Nonce to get the hash was 1
It took 0.000000 seconds to calculate

Hash was 0 0 0 0 0 0 0 0 6 203 214 123 135 127 0 0 64 216 207 126 253 127 0 0 129 219 214 123 135 127 0 0 0 235 234 123 135 127 0 0 16 216 207 126 253 127 0 0 2 0 0 0 0 0 0 0 176 217 207 126 253 127 0 0 
Nonce to get the hash was 1
It took 0.000000 seconds to calculate

Hash was 0 0 0 0 0 0 0 0 6 123 219 55 192 127 0 0 144 108 17 232 252 127 0 0 129 139 219 55 192 127 0 0 0 155 239 55 192 127 0 0 96 108 17 232 252 127 0 0 2 0 0 0 0 0 0 0 0 110 17 232 252 127 0 0 
Nonce to get the hash was 1
It took 0.000000 seconds to calculate

Hash was 0 0 0 0 0 0 0 0 6 107 181 157 222 127 0 0 64 183 143 12 253 127 0 0 129 123 181 157 222 127 0 0 0 139 201 157 222 127 0 0 16 183 143 12 253 127 0 0 2 0 0 0 0 0 0 0 176 184 143 12 253 127 0 0 
Nonce to get the hash was 1
It took 0.000000 seconds to calculate

Hash was 0 0 0 0 0 0 0 0 6 139 121 81 110 127 0 0 32 171 61 179 254 127 0 0 129 155 121 81 110 127 0 0 0 171 141 81 110 127 0 0 240 170 61 179 254 127 0 0 2 0 0 0 0 0 0 0 144 172 61 179 254 127 0 0 
Nonce to get the hash was 1
It took 0.000000 seconds to calculate
but5z9lq

but5z9lq1#

res_size未初始化。它包含垃圾,垃圾根据编译器标志的不同而不同。
另一方面,hash_memory期望它具有输出缓冲区的大小,它做的第一件事是检查是否有足够的空间提供,如果没有,它就退出。
因此,您看到的不是哈希值,而是缓冲区的初始状态。
始终测试返回值!

相关问题