Reputation: 301
I have a 16MB file. I want to take 16-byte chuck of the data each time, using SHA256 to hash it, and then use the result to point to the next location of the 16-byte chunk to be hashed.
For example,
#include <openssl/aes.h>
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BLOCKSIZE 1048576
#define SUBBLOCKSIZE 16
int main(void) {
SHA256_CTX ctx;
int SHA256_Init(SHA256_CTX *ctx);
u_int8_t results[32];
FILE *infile;
char buf[SUBBLOCKSIZE];
int bufsize = SUBBLOCKSIZE;
infile = fopen("sample.dat", "r");
int i = 0;
int n;
while (fread(buf, SUBBLOCKSIZE, 1, infile) != NULL) {
SHA256_Init(&ctx);
n = strlen(buf);
SHA256_Update(&ctx, (u_int8_t *)buf, n);
SHA256_Final(results, &ctx);
//fseek here.....
i++;
}
return 0;
}
In my code, 'results' is the hash result of SHA256. I want to convert it to a 256-bit number and mod it by 1024(or some other arbitrary integer number). Then I use the result as an input in fseek to locate to the next file pointer.
I'd like to know how can I convert 'results' to a 256-bit number?
Upvotes: 2
Views: 3904
Reputation: 94018
The direct answer would be to use a library that handles big integers. For C the OpenSSL BN_
functions perform operations on Big Numbers, to name just an obvious one.
The not-so direct answer is to simply use 64 bits/8 bytes (leftmost) bits of the 256 bits/32 bytes of the resulting array and put it into a 64 bit "long" number (int64_t
is probably best). Then you can simply retrieve the modulo x
of that value using the %
operator.
Beware that the result is not well distributed over the limit x
that are not powers of two. In that case you may need to discard any number r
that is equal or larger than x * n
where n
is the maximum value where x * n
still fits into 64 bits. If you don't discard those values then you have a (tiny) higher chance that the result will be a lower value.
Of course if your result is exactly a power p
of 2 then you might as well take the p
(leftmost) bits and interpret those bits as an unsigned integer of a size the same or higher.
Upvotes: 2