mirror of
https://github.com/Jimmy-Z/bfCL.git
synced 2025-06-18 11:05:49 -04:00
180 lines
3.9 KiB
C
180 lines
3.9 KiB
C
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <immintrin.h>
|
|
#include "utils.h"
|
|
|
|
#ifdef __GNUC__
|
|
#include <cpuid.h>
|
|
#elif _MSC_VER
|
|
#include <intrin.h>
|
|
#endif
|
|
|
|
int htoi(char a){
|
|
if(a >= '0' && a <= '9'){
|
|
return a - '0';
|
|
}else if(a >= 'a' && a <= 'f'){
|
|
return a - ('a' - 0xa);
|
|
}else if(a >= 'A' && a <= 'F'){
|
|
return a - ('A' - 0xa);
|
|
}else{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int hex2bytes(unsigned char *out, unsigned byte_len, const char *in, int critical){
|
|
if (strlen(in) != byte_len << 1){
|
|
fprintf(stderr, "%s: invalid input length, expecting %u, got %u.\n",
|
|
__FUNCTION__, (unsigned)byte_len << 1, (unsigned)strlen(in));
|
|
assert(!critical);
|
|
return -1;
|
|
}
|
|
for(unsigned i = 0; i < byte_len; ++i){
|
|
int h = htoi(*in++), l = htoi(*in++);
|
|
if(h == -1 || l == -1){
|
|
fprintf(stderr, "%s: invalid input \"%c%c\"\n",
|
|
__FUNCTION__, *(in - 2), *(in - 1));
|
|
assert(!critical);
|
|
return -2;
|
|
}
|
|
*out++ = (h << 4) + l;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifndef HEXDUMP_BUF_SIZE
|
|
#define HEXDUMP_BUF_SIZE 0x100
|
|
#endif
|
|
|
|
static char hexdump_buf[HEXDUMP_BUF_SIZE];
|
|
// CAUTION, this always assume the buffer is big enough
|
|
const char *hexdump(const void *b, unsigned l, int space){
|
|
const unsigned char *p = (unsigned char*)b;
|
|
char *out = hexdump_buf;
|
|
for(unsigned i = 0; i < l; ++i){
|
|
out += sprintf(out, "%02x", *p);
|
|
++p;
|
|
if(space && i < l - 1){
|
|
*out++ = ' ';
|
|
}
|
|
}
|
|
return hexdump_buf;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
long long hp_time_diff(LARGE_INTEGER *pt0, LARGE_INTEGER *pt1) {
|
|
LARGE_INTEGER freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
long long diff = pt1->QuadPart - pt0->QuadPart;
|
|
diff *= 1000000;
|
|
diff /= freq.QuadPart;
|
|
return diff;
|
|
}
|
|
|
|
#else
|
|
|
|
void get_hp_time(struct timeval *pt) {
|
|
gettimeofday(pt, NULL);
|
|
}
|
|
|
|
long long hp_time_diff(struct timeval *pt0, struct timeval *pt1) {
|
|
long long diff = pt1.tv_sec - pt0.tv_sec;
|
|
diff *= 1000000;
|
|
diff += pt1.tv_usec - pt0.tv_usec;
|
|
return diff;
|
|
}
|
|
|
|
#endif
|
|
|
|
// CAUTION: caller is responsible to free the buf
|
|
char * read_file(const char *file_name, size_t *p_size) {
|
|
FILE * f = fopen(file_name, "rb");
|
|
if (f == NULL) {
|
|
fprintf(stderr, "can't read file: %s", file_name);
|
|
exit(-1);
|
|
}
|
|
fseek(f, 0, SEEK_END);
|
|
*p_size = ftell(f);
|
|
char * buf = malloc(*p_size);
|
|
fseek(f, 0, SEEK_SET);
|
|
fread(buf, *p_size, 1, f);
|
|
fclose(f);
|
|
return buf;
|
|
}
|
|
|
|
void read_files(unsigned num_files, const char *file_names[], char *ptrs[], size_t sizes[]) {
|
|
for (unsigned i = 0; i < num_files; ++i) {
|
|
ptrs[i] = read_file(file_names[i], &sizes[i]);
|
|
}
|
|
}
|
|
|
|
void dump_to_file(const char *file_name, const void *buf, size_t len) {
|
|
FILE *f = fopen(file_name, "wb");
|
|
if (f == NULL) {
|
|
fprintf(stderr, "can't open file to write: %s\n", file_name);
|
|
return;
|
|
}
|
|
fwrite(buf, len, 1, f);
|
|
fclose(f);
|
|
}
|
|
|
|
int cpu_has_rdrand() {
|
|
#if __GNUC__
|
|
unsigned a = 0, b = 0, c = 0, d = 0;
|
|
__get_cpuid(1, &a, &b, &c, &d);
|
|
return c & bit_RDRND;
|
|
#elif _MSC_VER
|
|
int regs[4];
|
|
__cpuid(regs, 1);
|
|
return regs[2] & (1<<30);
|
|
#else
|
|
// ICL only?
|
|
return _may_i_use_cpu_feature(_FEATURE_RDRND);
|
|
#endif
|
|
}
|
|
|
|
// input must be multiple of uint64_t
|
|
int rdrand_fill(unsigned long long *p, size_t size) {
|
|
unsigned long long *p_end = p + size;
|
|
int success = 1;
|
|
while (p < p_end) {
|
|
success &= _rdrand64_step(p++);
|
|
}
|
|
return success;
|
|
}
|
|
|
|
inline int is_white_space(char c) {
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r';
|
|
}
|
|
|
|
// the crudest trim
|
|
// it works by:
|
|
// setting the char next to the last non ws char to '\0'
|
|
// return the pointer to the first non ws character
|
|
// so beware the input string got modified
|
|
// and the returned ptr becomes unavailable if the input is gone
|
|
// and if the input is malloced, you should save the ptr for free
|
|
char * trim(char *in) {
|
|
char *first_non_ws = 0;
|
|
char *last_non_ws = 0;
|
|
while (*in) {
|
|
if (!is_white_space(*in)) {
|
|
if (!first_non_ws) {
|
|
first_non_ws = in;
|
|
}
|
|
last_non_ws = in;
|
|
}
|
|
++in;
|
|
}
|
|
// cut the trailing
|
|
++last_non_ws;
|
|
if (last_non_ws < in) {
|
|
*last_non_ws = '\0';
|
|
}
|
|
return first_non_ws;
|
|
}
|
|
|