Skip to content

Commit 9efbb0c

Browse files
Add files via upload
1 parent 881a275 commit 9efbb0c

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed

directional_hash_rc2.c

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <stdint.h>
4+
#include <string.h>
5+
#include <openssl/sha.h>
6+
#include <openssl/evp.h>
7+
#include <omp.h>
8+
#include <unistd.h>
9+
#include <time.h>
10+
11+
#define CHUNK_SIZE 8192
12+
13+
typedef struct {
14+
int r, c;
15+
int weight;
16+
} CoordWeight;
17+
18+
// Forward declaration of to_grid
19+
void to_grid(uint8_t byte, char grid[3][3]);
20+
// Precompute weighted patterns for all 256 byte values
21+
uint8_t precomputed_coords[256][8][2];
22+
23+
// Precompute weighted patterns
24+
void precompute_weighted_patterns() {
25+
for (int byte = 0; byte < 256; byte++) {
26+
char grid[3][3];
27+
to_grid(byte, grid);
28+
29+
CoordWeight coords[9];
30+
int count = 0;
31+
32+
int position_bias[3][3] = {
33+
{3, 2, 3},
34+
{2, 4, 2},
35+
{3, 2, 3}
36+
};
37+
38+
for (int r = 0; r < 3; r++) {
39+
for (int c = 0; c < 3; c++) {
40+
if (grid[r][c] != '\0') {
41+
coords[count].r = r;
42+
coords[count].c = c;
43+
coords[count].weight = (grid[r][c] == '1' ? 10 : 5) + position_bias[r][c];
44+
count++;
45+
}
46+
}
47+
}
48+
49+
// Sort by weight descending
50+
for (int i = 0; i < count - 1; i++) {
51+
for (int j = i + 1; j < count; j++) {
52+
if (coords[j].weight > coords[i].weight) {
53+
CoordWeight temp = coords[i];
54+
coords[i] = coords[j];
55+
coords[j] = temp;
56+
}
57+
}
58+
}
59+
60+
for (int i = 0; i < 8; i++) {
61+
precomputed_coords[byte][i][0] = (i < count) ? coords[i].r : -1; // Prevent out of bounds
62+
precomputed_coords[byte][i][1] = (i < count) ? coords[i].c : -1; // Prevent out of bounds
63+
}
64+
}
65+
}
66+
67+
// Converts a byte to a 3x3 grid with 1 blank (None)
68+
void to_grid(uint8_t byte, char grid[3][3]) {
69+
char bits[9] = {0};
70+
for (int i = 0; i < 8; i++) {
71+
bits[i] = ((byte >> (7 - i)) & 1) + '0';
72+
}
73+
bits[8] = '\0';
74+
75+
int k = 0;
76+
for (int r = 0; r < 3; r++) {
77+
for (int c = 0; c < 3; c++) {
78+
if (k < 8)
79+
grid[r][c] = bits[k++];
80+
else
81+
grid[r][c] = '\0'; // blank
82+
}
83+
}
84+
}
85+
86+
// Flattens the grid using the precomputed weighted order
87+
void flatten(char grid[3][3], char* out, uint8_t byte) {
88+
int idx = 0;
89+
for (int i = 0; i < 8; i++) {
90+
int r = precomputed_coords[byte][i][0];
91+
int c = precomputed_coords[byte][i][1];
92+
if (r >= 0 && r < 3 && c >= 0 && c < 3 && grid[r][c] != '\0') {
93+
out[idx++] = grid[r][c];
94+
}
95+
}
96+
out[idx] = '\0';
97+
}
98+
99+
// Processes a byte with precomputed weighted read pattern
100+
void process_byte(uint8_t byte, char* out) {
101+
char grid[3][3];
102+
to_grid(byte, grid);
103+
104+
flatten(grid, out, byte);
105+
}
106+
107+
void directional_hash_file(const char* filename, int bits, int chunk_size, int max_workers) {
108+
FILE* file = fopen(filename, "rb");
109+
if (!file) {
110+
perror("Failed to open file");
111+
return;
112+
}
113+
114+
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
115+
const EVP_MD* md = NULL;
116+
117+
switch (bits) {
118+
case 256:
119+
md = EVP_sha256(); break;
120+
case 512:
121+
md = EVP_sha512(); break;
122+
case 1024:
123+
case 2048:
124+
md = EVP_shake256(); break;
125+
default:
126+
fprintf(stderr, "Unsupported bit size: %d\n", bits);
127+
fclose(file);
128+
return;
129+
}
130+
131+
EVP_DigestInit_ex(ctx, md, NULL);
132+
133+
uint8_t buffer[chunk_size];
134+
size_t read;
135+
char* bin = malloc(33 * chunk_size * sizeof(char));
136+
size_t bin_index = 0;
137+
138+
if (!bin) {
139+
perror("Failed to allocate memory for bin");
140+
EVP_MD_CTX_free(ctx);
141+
fclose(file);
142+
return;
143+
}
144+
145+
while ((read = fread(buffer, 1, chunk_size, file)) > 0) {
146+
// Allocate thread-local buffers outside parallel region
147+
char** processed_array = malloc(read * sizeof(char*));
148+
149+
#pragma omp parallel for num_threads(max_workers)
150+
for (size_t j = 0; j < read; j++) {
151+
processed_array[j] = malloc(1024); // allocate per thread
152+
processed_array[j][0] = '\0';
153+
process_byte(buffer[j], processed_array[j]);
154+
}
155+
156+
bin[0] = '\0';
157+
for (size_t j = 0; j < read; j++) {
158+
// Use safer string copy method
159+
strcat(bin, processed_array[j]);
160+
free(processed_array[j]);
161+
}
162+
free(processed_array);
163+
164+
size_t len = strlen(bin);
165+
size_t byte_len = (len + 7) / 8;
166+
uint8_t* byte_buf = malloc(byte_len);
167+
memset(byte_buf, 0, byte_len);
168+
169+
for (size_t i = 0; i < len; i++) {
170+
if (bin[i] == '1') {
171+
byte_buf[i / 8] |= 1 << (7 - (i % 8));
172+
}
173+
}
174+
175+
EVP_DigestUpdate(ctx, byte_buf, byte_len);
176+
free(byte_buf);
177+
bin[0] = '\0';
178+
}
179+
180+
size_t hash_output_size = bits / 8;
181+
unsigned char hash[EVP_MAX_MD_SIZE * 4];
182+
183+
if (bits == 1024 || bits == 2048) {
184+
EVP_DigestFinalXOF(ctx, hash, hash_output_size);
185+
} else {
186+
unsigned int hash_len = 0;
187+
EVP_DigestFinal_ex(ctx, hash, &hash_len);
188+
hash_output_size = (size_t)hash_len;
189+
}
190+
191+
for (size_t i = 0; i < hash_output_size; i++) {
192+
printf("%02x", hash[i]);
193+
}
194+
printf("\n");
195+
196+
free(bin);
197+
EVP_MD_CTX_free(ctx);
198+
fclose(file);
199+
}
200+
201+
int main(int argc, char* argv[]) {
202+
if (argc < 2) {
203+
fprintf(stderr, "Usage: %s <file> [bits=256|512|1024|2048] [chunk_size=8192] [max_workers=4] [--time]\n", argv[0]);
204+
return 1;
205+
}
206+
207+
int bits = 256;
208+
int chunk_size = 8192;
209+
int max_workers = 4;
210+
int time_flag = 0;
211+
212+
for (int i = 1; i < argc; i++) {
213+
if (strcmp(argv[i], "--time") == 0) {
214+
time_flag = 1;
215+
}
216+
}
217+
218+
if (argc > 2) bits = atoi(argv[2]);
219+
if (argc > 3) chunk_size = atoi(argv[3]);
220+
if (argc > 4) max_workers = atoi(argv[4]);
221+
222+
// Precompute all weight orders
223+
precompute_weighted_patterns();
224+
225+
struct timespec start, end;
226+
if (time_flag) {
227+
clock_gettime(CLOCK_MONOTONIC, &start);
228+
}
229+
230+
directional_hash_file(argv[1], bits, chunk_size, max_workers);
231+
232+
if (time_flag) {
233+
clock_gettime(CLOCK_MONOTONIC, &end);
234+
double elapsed = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
235+
printf("Time elapsed: %.6f seconds\n", elapsed);
236+
}
237+
return 0;
238+
}

0 commit comments

Comments
 (0)