Added basecode, sha256, rmd160, bas58 and bloomfilter

This commit is contained in:
AlbertoBSD
2020-12-17 19:05:34 +01:00
parent 37eba63a7a
commit 1f1a9bd347
16 changed files with 2589 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.txt
# Prerequisites
*.d

11
Makefile Executable file
View File

@@ -0,0 +1,11 @@
default:
gcc -O3 -c bloom/bloom.c -o bloom.o -I./bloom/murmur2
gcc -O3 -c bloom/murmur2/MurmurHash2.c -o murmurhash2.o
gcc -O3 -c sha256/sha256.c -o sha256.o
gcc -O3 -c base58/base58.c -o base58.o
gcc -O3 -c rmd160/rmd160.c -o rmd160.o
gcc -O3 -c keyhunt.c -o keyhunt.o
gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o murmurhash2.o -lgmp -lm -lpthread
clean:
rm -r *.o

205
base58/base58.c Normal file
View File

@@ -0,0 +1,205 @@
/*
* Copyright 2012-2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#ifndef WIN32
#include <arpa/inet.h>
#else
#include <winsock2.h>
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "libbase58.h"
bool (*b58_sha256_impl)(void *, const void *, size_t) = NULL;
static const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
typedef uint64_t b58_maxint_t;
typedef uint32_t b58_almostmaxint_t;
#define b58_almostmaxint_bits (sizeof(b58_almostmaxint_t) * 8)
static const b58_almostmaxint_t b58_almostmaxint_mask = ((((b58_maxint_t)1) << b58_almostmaxint_bits) - 1);
bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
{
size_t binsz = *binszp;
const unsigned char *b58u = (void*)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t);
b58_almostmaxint_t outi[outisz];
b58_maxint_t t;
b58_almostmaxint_t c;
size_t i, j;
uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t);
b58_almostmaxint_t zeromask = bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
if (!b58sz)
b58sz = strlen(b58);
for (i = 0; i < outisz; ++i) {
outi[i] = 0;
}
// Leading zeros, just count
for (i = 0; i < b58sz && b58u[i] == '1'; ++i)
++zerocount;
for ( ; i < b58sz; ++i)
{
if (b58u[i] & 0x80)
// High-bit set on invalid digit
return false;
if (b58digits_map[b58u[i]] == -1)
// Invalid base58 digit
return false;
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--; )
{
t = ((b58_maxint_t)outi[j]) * 58 + c;
c = t >> b58_almostmaxint_bits;
outi[j] = t & b58_almostmaxint_mask;
}
if (c)
// Output number too big (carry to the next int32)
return false;
if (outi[0] & zeromask)
// Output number too big (last int32 filled too far)
return false;
}
j = 0;
if (bytesleft) {
for (i = bytesleft; i > 0; --i) {
*(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff;
}
++j;
}
for (; j < outisz; ++j)
{
for (i = sizeof(*outi); i > 0; --i) {
*(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff;
}
}
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{
if (binu[i])
break;
--*binszp;
}
*binszp += zerocount;
return true;
}
static
bool my_dblsha256(void *hash, const void *data, size_t datasz)
{
uint8_t buf[0x20];
return b58_sha256_impl(buf, data, datasz) && b58_sha256_impl(hash, buf, sizeof(buf));
}
int b58check(const void *bin, size_t binsz, const char *base58str, size_t b58sz)
{
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
if (!my_dblsha256(buf, bin, binsz - 4))
return -2;
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
return binc[0];
}
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
{
const uint8_t *bin = data;
int carry;
size_t i, j, high, zcount = 0;
size_t size;
while (zcount < binsz && !bin[zcount])
++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memset(buf, 0, size);
for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
if (!j) {
// Otherwise j wraps to maxint which is > high
break;
}
}
}
for (j = 0; j < size && !buf[j]; ++j);
if (*b58sz <= zcount + size - j)
{
*b58sz = zcount + size - j + 1;
return false;
}
if (zcount)
memset(b58, '1', zcount);
for (i = zcount; j < size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
*b58sz = i + 1;
return true;
}
bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz)
{
uint8_t buf[1 + datasz + 0x20];
uint8_t *hash = &buf[1 + datasz];
buf[0] = ver;
memcpy(&buf[1], data, datasz);
if (!my_dblsha256(hash, buf, datasz + 1))
{
*b58c_sz = 0;
return false;
}
return b58enc(b58c, b58c_sz, buf, 1 + datasz + 4);
}

23
base58/libbase58.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef LIBBASE58_H
#define LIBBASE58_H
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
extern bool (*b58_sha256_impl)(void *, const void *, size_t);
extern bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz);
extern int b58check(const void *bin, size_t binsz, const char *b58, size_t b58sz);
extern bool b58enc(char *b58, size_t *b58sz, const void *bin, size_t binsz);
extern bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz);
#ifdef __cplusplus
}
#endif
#endif

26
bloom/LICENSE Normal file
View File

@@ -0,0 +1,26 @@
Copyright (c) 2012,2015,2016,2017 Jyri J. Virkki
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

167
bloom/bloom.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2012-2019, Jyri J. Virkki
* All rights reserved.
*
* This file is under BSD license. See LICENSE file.
*/
/*
* Refer to bloom.h for documentation on the public interfaces.
*/
#include <assert.h>
#include <fcntl.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "bloom.h"
#include "murmurhash2.h"
#define MAKESTRING(n) STRING(n)
#define STRING(n) #n
inline static int test_bit_set_bit(unsigned char * buf,
unsigned int x, int set_bit)
{
unsigned int byte = x >> 3;
unsigned char c = buf[byte]; // expensive memory access
unsigned int mask = 1 << (x % 8);
if (c & mask) {
return 1;
} else {
if (set_bit) {
buf[byte] = c | mask;
}
return 0;
}
}
static int bloom_check_add(struct bloom * bloom,
const void * buffer, int len, int add)
{
if (bloom->ready == 0) {
printf("bloom at %p not initialized!\n", (void *)bloom);
return -1;
}
int hits = 0;
register unsigned int a = murmurhash2(buffer, len, 0x9747b28c);
register unsigned int b = murmurhash2(buffer, len, a);
register unsigned int x;
register unsigned int i;
for (i = 0; i < bloom->hashes; i++) {
x = (a + i*b) % bloom->bits;
if (test_bit_set_bit(bloom->bf, x, add)) {
hits++;
} else if (!add) {
// Don't care about the presence of all the bits. Just our own.
return 0;
}
}
if (hits == bloom->hashes) {
return 1; // 1 == element already in (or collision)
}
return 0;
}
int bloom_init_size(struct bloom * bloom, int entries, double error,
unsigned int cache_size)
{
return bloom_init(bloom, entries, error);
}
int bloom_init(struct bloom * bloom, int entries, double error)
{
bloom->ready = 0;
if (entries < 1000 || error == 0) {
return 1;
}
bloom->entries = entries;
bloom->error = error;
double num = log(bloom->error);
double denom = 0.480453013918201; // ln(2)^2
bloom->bpe = -(num / denom);
double dentries = (double)entries;
bloom->bits = (int)(dentries * bloom->bpe);
if (bloom->bits % 8) {
bloom->bytes = (bloom->bits / 8) + 1;
} else {
bloom->bytes = bloom->bits / 8;
}
bloom->hashes = (int)ceil(0.693147180559945 * bloom->bpe); // ln(2)
bloom->bf = (unsigned char *)calloc(bloom->bytes, sizeof(unsigned char));
if (bloom->bf == NULL) { // LCOV_EXCL_START
return 1;
} // LCOV_EXCL_STOP
bloom->ready = 1;
return 0;
}
int bloom_check(struct bloom * bloom, const void * buffer, int len)
{
return bloom_check_add(bloom, buffer, len, 0);
}
int bloom_add(struct bloom * bloom, const void * buffer, int len)
{
return bloom_check_add(bloom, buffer, len, 1);
}
void bloom_print(struct bloom * bloom)
{
printf("bloom at %p\n", (void *)bloom);
printf(" ->entries = %d\n", bloom->entries);
printf(" ->error = %f\n", bloom->error);
printf(" ->bits = %d\n", bloom->bits);
printf(" ->bits per elem = %f\n", bloom->bpe);
printf(" ->bytes = %d\n", bloom->bytes);
printf(" ->hash functions = %d\n", bloom->hashes);
}
void bloom_free(struct bloom * bloom)
{
if (bloom->ready) {
free(bloom->bf);
}
bloom->ready = 0;
}
int bloom_reset(struct bloom * bloom)
{
if (!bloom->ready) return 1;
memset(bloom->bf, 0, bloom->bytes);
return 0;
}
const char * bloom_version()
{
return MAKESTRING(BLOOM_VERSION);
}

173
bloom/bloom.h Normal file
View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2012-2017, Jyri J. Virkki
* All rights reserved.
*
* This file is under BSD license. See LICENSE file.
*/
#ifndef _BLOOM_H
#define _BLOOM_H
#ifdef __cplusplus
extern "C" {
#endif
/** ***************************************************************************
* Structure to keep track of one bloom filter. Caller needs to
* allocate this and pass it to the functions below. First call for
* every struct must be to bloom_init().
*
*/
struct bloom
{
// These fields are part of the public interface of this structure.
// Client code may read these values if desired. Client code MUST NOT
// modify any of these.
int entries;
double error;
int bits;
int bytes;
int hashes;
// Fields below are private to the implementation. These may go away or
// change incompatibly at any moment. Client code MUST NOT access or rely
// on these.
double bpe;
unsigned char * bf;
int ready;
};
/** ***************************************************************************
* Initialize the bloom filter for use.
*
* The filter is initialized with a bit field and number of hash functions
* according to the computations from the wikipedia entry:
* http://en.wikipedia.org/wiki/Bloom_filter
*
* Optimal number of bits is:
* bits = (entries * ln(error)) / ln(2)^2
*
* Optimal number of hash functions is:
* hashes = bpe * ln(2)
*
* Parameters:
* -----------
* bloom - Pointer to an allocated struct bloom (see above).
* entries - The expected number of entries which will be inserted.
* Must be at least 1000 (in practice, likely much larger).
* error - Probability of collision (as long as entries are not
* exceeded).
*
* Return:
* -------
* 0 - on success
* 1 - on failure
*
*/
int bloom_init(struct bloom * bloom, int entries, double error);
/** ***************************************************************************
* Deprecated, use bloom_init()
*
*/
int bloom_init_size(struct bloom * bloom, int entries, double error,
unsigned int cache_size);
/** ***************************************************************************
* Check if the given element is in the bloom filter. Remember this may
* return false positive if a collision occurred.
*
* Parameters:
* -----------
* bloom - Pointer to an allocated struct bloom (see above).
* buffer - Pointer to buffer containing element to check.
* len - Size of 'buffer'.
*
* Return:
* -------
* 0 - element is not present
* 1 - element is present (or false positive due to collision)
* -1 - bloom not initialized
*
*/
int bloom_check(struct bloom * bloom, const void * buffer, int len);
/** ***************************************************************************
* Add the given element to the bloom filter.
* The return code indicates if the element (or a collision) was already in,
* so for the common check+add use case, no need to call check separately.
*
* Parameters:
* -----------
* bloom - Pointer to an allocated struct bloom (see above).
* buffer - Pointer to buffer containing element to add.
* len - Size of 'buffer'.
*
* Return:
* -------
* 0 - element was not present and was added
* 1 - element (or a collision) had already been added previously
* -1 - bloom not initialized
*
*/
int bloom_add(struct bloom * bloom, const void * buffer, int len);
/** ***************************************************************************
* Print (to stdout) info about this bloom filter. Debugging aid.
*
*/
void bloom_print(struct bloom * bloom);
/** ***************************************************************************
* Deallocate internal storage.
*
* Upon return, the bloom struct is no longer usable. You may call bloom_init
* again on the same struct to reinitialize it again.
*
* Parameters:
* -----------
* bloom - Pointer to an allocated struct bloom (see above).
*
* Return: none
*
*/
void bloom_free(struct bloom * bloom);
/** ***************************************************************************
* Erase internal storage.
*
* Erases all elements. Upon return, the bloom struct returns to its initial
* (initialized) state.
*
* Parameters:
* -----------
* bloom - Pointer to an allocated struct bloom (see above).
*
* Return:
* 0 - on success
* 1 - on failure
*
*/
int bloom_reset(struct bloom * bloom);
/** ***************************************************************************
* Returns version string compiled into library.
*
* Return: version string
*
*/
const char * bloom_version();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,64 @@
//-----------------------------------------------------------------------------
// MurmurHash2, by Austin Appleby
// Note - This code makes a few assumptions about how your machine behaves -
// 1. We can read a 4-byte value from any address without crashing
// 2. sizeof(int) == 4
// And it has a few limitations -
// 1. It will not work incrementally.
// 2. It will not produce the same results on little-endian and big-endian
// machines.
unsigned int murmurhash2(const void * key, int len, const unsigned int seed)
{
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
const unsigned int m = 0x5bd1e995;
const int r = 24;
// Initialize the hash to a 'random' value
unsigned int h = seed ^ len;
// Mix 4 bytes at a time into the hash
const unsigned char * data = (const unsigned char *)key;
while(len >= 4)
{
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
// Handle the last few bytes of the input array
switch(len)
{
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
h *= m;
};
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}

9
bloom/murmur2/README Normal file
View File

@@ -0,0 +1,9 @@
MurmurHash2.c is taken from
http://sites.google.com/site/murmurhash/
According to the above document:
All code is released to the public domain. For business purposes,
Murmurhash is under the MIT license.

View File

@@ -0,0 +1,7 @@
#ifndef _BLOOM_MURMURHASH2
#define _BLOOM_MURMURHASH2
unsigned int murmurhash2(const void * key, int len, const unsigned int seed);
#endif

1067
keyhunt.c Normal file

File diff suppressed because it is too large Load Diff

450
rmd160/rmd160.c Normal file
View File

@@ -0,0 +1,450 @@
/*
* RIPEMD160.c - European RIPE Message Digest, 160 bit (RIPEMD-160)
*
* The algorithm is by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel.
*
* The code below is based on the reference implementation by Bosselaers.
* It is available at the time of writing from
* http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
*
* Hacked for use in libmd by Martin Hinner <mhi@penguin.cz>
*/
#include <string.h>
#include "rmd160.h"
/* macro definitions */
/* ROL(x, n) cyclically rotates x over n bits to the left */
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* the three basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define II(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define FFF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GGG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HHH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define III(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
/*
initializes MDbuffer to "magic constants"
*/
static void
RMDinit (u_int32_t * MDbuf)
{
MDbuf[0] = 0x67452301UL;
MDbuf[1] = 0xefcdab89UL;
MDbuf[2] = 0x98badcfeUL;
MDbuf[3] = 0x10325476UL;
MDbuf[4] = 0xc3d2e1f0UL;
}
/*
the compression function.
transforms MDbuf using message bytes X[0] through X[15]
*/
static void
RMDcompress (u_int32_t * MDbuf, u_int32_t * X)
{
u_int32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
dd = MDbuf[3], ee = MDbuf[4];
u_int32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
ddd = MDbuf[3], eee = MDbuf[4];
/* round 1 */
FF (aa, bb, cc, dd, ee, X[0], 11);
FF (ee, aa, bb, cc, dd, X[1], 14);
FF (dd, ee, aa, bb, cc, X[2], 15);
FF (cc, dd, ee, aa, bb, X[3], 12);
FF (bb, cc, dd, ee, aa, X[4], 5);
FF (aa, bb, cc, dd, ee, X[5], 8);
FF (ee, aa, bb, cc, dd, X[6], 7);
FF (dd, ee, aa, bb, cc, X[7], 9);
FF (cc, dd, ee, aa, bb, X[8], 11);
FF (bb, cc, dd, ee, aa, X[9], 13);
FF (aa, bb, cc, dd, ee, X[10], 14);
FF (ee, aa, bb, cc, dd, X[11], 15);
FF (dd, ee, aa, bb, cc, X[12], 6);
FF (cc, dd, ee, aa, bb, X[13], 7);
FF (bb, cc, dd, ee, aa, X[14], 9);
FF (aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG (ee, aa, bb, cc, dd, X[7], 7);
GG (dd, ee, aa, bb, cc, X[4], 6);
GG (cc, dd, ee, aa, bb, X[13], 8);
GG (bb, cc, dd, ee, aa, X[1], 13);
GG (aa, bb, cc, dd, ee, X[10], 11);
GG (ee, aa, bb, cc, dd, X[6], 9);
GG (dd, ee, aa, bb, cc, X[15], 7);
GG (cc, dd, ee, aa, bb, X[3], 15);
GG (bb, cc, dd, ee, aa, X[12], 7);
GG (aa, bb, cc, dd, ee, X[0], 12);
GG (ee, aa, bb, cc, dd, X[9], 15);
GG (dd, ee, aa, bb, cc, X[5], 9);
GG (cc, dd, ee, aa, bb, X[2], 11);
GG (bb, cc, dd, ee, aa, X[14], 7);
GG (aa, bb, cc, dd, ee, X[11], 13);
GG (ee, aa, bb, cc, dd, X[8], 12);
/* round 3 */
HH (dd, ee, aa, bb, cc, X[3], 11);
HH (cc, dd, ee, aa, bb, X[10], 13);
HH (bb, cc, dd, ee, aa, X[14], 6);
HH (aa, bb, cc, dd, ee, X[4], 7);
HH (ee, aa, bb, cc, dd, X[9], 14);
HH (dd, ee, aa, bb, cc, X[15], 9);
HH (cc, dd, ee, aa, bb, X[8], 13);
HH (bb, cc, dd, ee, aa, X[1], 15);
HH (aa, bb, cc, dd, ee, X[2], 14);
HH (ee, aa, bb, cc, dd, X[7], 8);
HH (dd, ee, aa, bb, cc, X[0], 13);
HH (cc, dd, ee, aa, bb, X[6], 6);
HH (bb, cc, dd, ee, aa, X[13], 5);
HH (aa, bb, cc, dd, ee, X[11], 12);
HH (ee, aa, bb, cc, dd, X[5], 7);
HH (dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II (cc, dd, ee, aa, bb, X[1], 11);
II (bb, cc, dd, ee, aa, X[9], 12);
II (aa, bb, cc, dd, ee, X[11], 14);
II (ee, aa, bb, cc, dd, X[10], 15);
II (dd, ee, aa, bb, cc, X[0], 14);
II (cc, dd, ee, aa, bb, X[8], 15);
II (bb, cc, dd, ee, aa, X[12], 9);
II (aa, bb, cc, dd, ee, X[4], 8);
II (ee, aa, bb, cc, dd, X[13], 9);
II (dd, ee, aa, bb, cc, X[3], 14);
II (cc, dd, ee, aa, bb, X[7], 5);
II (bb, cc, dd, ee, aa, X[15], 6);
II (aa, bb, cc, dd, ee, X[14], 8);
II (ee, aa, bb, cc, dd, X[5], 6);
II (dd, ee, aa, bb, cc, X[6], 5);
II (cc, dd, ee, aa, bb, X[2], 12);
/* round 5 */
JJ (bb, cc, dd, ee, aa, X[4], 9);
JJ (aa, bb, cc, dd, ee, X[0], 15);
JJ (ee, aa, bb, cc, dd, X[5], 5);
JJ (dd, ee, aa, bb, cc, X[9], 11);
JJ (cc, dd, ee, aa, bb, X[7], 6);
JJ (bb, cc, dd, ee, aa, X[12], 8);
JJ (aa, bb, cc, dd, ee, X[2], 13);
JJ (ee, aa, bb, cc, dd, X[10], 12);
JJ (dd, ee, aa, bb, cc, X[14], 5);
JJ (cc, dd, ee, aa, bb, X[1], 12);
JJ (bb, cc, dd, ee, aa, X[3], 13);
JJ (aa, bb, cc, dd, ee, X[8], 14);
JJ (ee, aa, bb, cc, dd, X[11], 11);
JJ (dd, ee, aa, bb, cc, X[6], 8);
JJ (cc, dd, ee, aa, bb, X[15], 5);
JJ (bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ (aaa, bbb, ccc, ddd, eee, X[5], 8);
JJJ (eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ (ddd, eee, aaa, bbb, ccc, X[7], 9);
JJJ (ccc, ddd, eee, aaa, bbb, X[0], 11);
JJJ (bbb, ccc, ddd, eee, aaa, X[9], 13);
JJJ (aaa, bbb, ccc, ddd, eee, X[2], 15);
JJJ (eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ (ddd, eee, aaa, bbb, ccc, X[4], 5);
JJJ (ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ (bbb, ccc, ddd, eee, aaa, X[6], 7);
JJJ (aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ (eee, aaa, bbb, ccc, ddd, X[8], 11);
JJJ (ddd, eee, aaa, bbb, ccc, X[1], 14);
JJJ (ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ (bbb, ccc, ddd, eee, aaa, X[3], 12);
JJJ (aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III (eee, aaa, bbb, ccc, ddd, X[6], 9);
III (ddd, eee, aaa, bbb, ccc, X[11], 13);
III (ccc, ddd, eee, aaa, bbb, X[3], 15);
III (bbb, ccc, ddd, eee, aaa, X[7], 7);
III (aaa, bbb, ccc, ddd, eee, X[0], 12);
III (eee, aaa, bbb, ccc, ddd, X[13], 8);
III (ddd, eee, aaa, bbb, ccc, X[5], 9);
III (ccc, ddd, eee, aaa, bbb, X[10], 11);
III (bbb, ccc, ddd, eee, aaa, X[14], 7);
III (aaa, bbb, ccc, ddd, eee, X[15], 7);
III (eee, aaa, bbb, ccc, ddd, X[8], 12);
III (ddd, eee, aaa, bbb, ccc, X[12], 7);
III (ccc, ddd, eee, aaa, bbb, X[4], 6);
III (bbb, ccc, ddd, eee, aaa, X[9], 15);
III (aaa, bbb, ccc, ddd, eee, X[1], 13);
III (eee, aaa, bbb, ccc, ddd, X[2], 11);
/* parallel round 3 */
HHH (ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH (ccc, ddd, eee, aaa, bbb, X[5], 7);
HHH (bbb, ccc, ddd, eee, aaa, X[1], 15);
HHH (aaa, bbb, ccc, ddd, eee, X[3], 11);
HHH (eee, aaa, bbb, ccc, ddd, X[7], 8);
HHH (ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH (ccc, ddd, eee, aaa, bbb, X[6], 6);
HHH (bbb, ccc, ddd, eee, aaa, X[9], 14);
HHH (aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH (eee, aaa, bbb, ccc, ddd, X[8], 13);
HHH (ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH (ccc, ddd, eee, aaa, bbb, X[2], 14);
HHH (bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH (aaa, bbb, ccc, ddd, eee, X[0], 13);
HHH (eee, aaa, bbb, ccc, ddd, X[4], 7);
HHH (ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG (ccc, ddd, eee, aaa, bbb, X[8], 15);
GGG (bbb, ccc, ddd, eee, aaa, X[6], 5);
GGG (aaa, bbb, ccc, ddd, eee, X[4], 8);
GGG (eee, aaa, bbb, ccc, ddd, X[1], 11);
GGG (ddd, eee, aaa, bbb, ccc, X[3], 14);
GGG (ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG (bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG (aaa, bbb, ccc, ddd, eee, X[0], 14);
GGG (eee, aaa, bbb, ccc, ddd, X[5], 6);
GGG (ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG (ccc, ddd, eee, aaa, bbb, X[2], 12);
GGG (bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG (aaa, bbb, ccc, ddd, eee, X[9], 12);
GGG (eee, aaa, bbb, ccc, ddd, X[7], 5);
GGG (ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG (ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF (bbb, ccc, ddd, eee, aaa, X[12], 8);
FFF (aaa, bbb, ccc, ddd, eee, X[15], 5);
FFF (eee, aaa, bbb, ccc, ddd, X[10], 12);
FFF (ddd, eee, aaa, bbb, ccc, X[4], 9);
FFF (ccc, ddd, eee, aaa, bbb, X[1], 12);
FFF (bbb, ccc, ddd, eee, aaa, X[5], 5);
FFF (aaa, bbb, ccc, ddd, eee, X[8], 14);
FFF (eee, aaa, bbb, ccc, ddd, X[7], 6);
FFF (ddd, eee, aaa, bbb, ccc, X[6], 8);
FFF (ccc, ddd, eee, aaa, bbb, X[2], 13);
FFF (bbb, ccc, ddd, eee, aaa, X[13], 6);
FFF (aaa, bbb, ccc, ddd, eee, X[14], 5);
FFF (eee, aaa, bbb, ccc, ddd, X[0], 15);
FFF (ddd, eee, aaa, bbb, ccc, X[3], 13);
FFF (ccc, ddd, eee, aaa, bbb, X[9], 11);
FFF (bbb, ccc, ddd, eee, aaa, X[11], 11);
/* combine results */
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
MDbuf[1] = MDbuf[2] + dd + eee;
MDbuf[2] = MDbuf[3] + ee + aaa;
MDbuf[3] = MDbuf[4] + aa + bbb;
MDbuf[4] = MDbuf[0] + bb + ccc;
MDbuf[0] = ddd;
}
/*
puts bytes from strptr into X and pad out; appends length
and finally, compresses the last block(s)
note: length in bits == 8 * (lswlen + 2^32 mswlen).
note: there are (lswlen mod 64) bytes left in strptr.
*/
static void
RMDFinish (u_int32_t * MDbuf, u_int8_t * strptr, u_int32_t lswlen,
u_int32_t mswlen)
{
u_int32_t i; /* counter */
u_int32_t X[16]; /* message words */
memset (X, 0, 16 * sizeof (u_int32_t));
/* put bytes from strptr into X */
for (i = 0; i < (lswlen & 63); i++)
{
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
X[i >> 2] ^= (u_int32_t) * strptr++ << (8 * (i & 3));
}
/* append the bit m_n == 1 */
X[(lswlen >> 2) & 15] ^= (u_int32_t) 1 << (8 * (lswlen & 3) + 7);
if ((lswlen & 63) > 55)
{
/* length goes to next block */
RMDcompress (MDbuf, X);
memset (X, 0, 16 * sizeof (u_int32_t));
}
/* append length in bits */
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
RMDcompress (MDbuf, X);
}
/*
Shuffle the bytes into little-endian order within words, as per the
RIPEMD-160 spec (which follows MD4 conventions).
*/
static void
rmd160ByteSwap (u_int32_t * dest, u_int8_t const *src, unsigned int words)
{
do
{
*dest++ = (u_int32_t) ((unsigned) src[3] << 8 | src[2]) << 16 |
((unsigned) src[1] << 8 | src[0]);
src += 4;
}
while (--words);
}
/*
Initialize the RIPEMD-160 values
*/
void
RMD160Init (RMD160_CTX * ctx)
{
/* Set the h-vars to their initial values */
RMDinit (ctx->iv);
/* Initialise bit count */
ctx->bytesHi = 0;
ctx->bytesLo = 0;
}
/*
Update the RIPEMD-160 hash state for a block of data.
*/
void RMD160Update(RMD160_CTX *ctx, const unsigned char *buf, unsigned int len)
{
unsigned i;
/* Update bitcount */
u_int32_t t = ctx->bytesLo;
if ((ctx->bytesLo = t + len) < t)
ctx->bytesHi++; /* Carry from low to high */
i = (unsigned) t % RIPEMD160_BLOCKBYTES; /* Bytes already in ctx->key */
/* i is always less than RIPEMD160_BLOCKBYTES. */
if (RIPEMD160_BLOCKBYTES - i > len)
{
memcpy ((u_int8_t *) ctx->key + i, buf, len);
return;
}
if (i)
{ /* First chunk is an odd size */
memcpy ((u_int8_t *) ctx->key + i, buf, RIPEMD160_BLOCKBYTES - i);
rmd160ByteSwap (ctx->key, (u_int8_t *) ctx->key, RIPEMD160_BLOCKWORDS);
RMDcompress (ctx->iv, ctx->key);
buf += RIPEMD160_BLOCKBYTES - i;
len -= RIPEMD160_BLOCKBYTES - i;
}
/* Process data in 64-byte chunks */
while (len >= RIPEMD160_BLOCKBYTES)
{
rmd160ByteSwap (ctx->key, buf, RIPEMD160_BLOCKWORDS);
RMDcompress (ctx->iv, ctx->key);
buf += RIPEMD160_BLOCKBYTES;
len -= RIPEMD160_BLOCKBYTES;
}
/* Handle any remaining bytes of data. */
if (len)
memcpy (ctx->key, buf, len);
}
/*
Final wrapup - MD4 style padding on last block.
*/
void
RMD160Final (unsigned char digest[20], RMD160_CTX * ctx)
{
int i;
u_int32_t t;
RMDFinish (ctx->iv, (u_int8_t *) ctx->key, ctx->bytesLo, ctx->bytesHi);
for (i = 0; i < RIPEMD160_HASHWORDS; i++)
{
t = ctx->iv[i];
digest[i * 4 + 0] = (u_int8_t) t;
digest[i * 4 + 1] = (u_int8_t) (t >> 8);
digest[i * 4 + 2] = (u_int8_t) (t >> 16);
digest[i * 4 + 3] = (u_int8_t) (t >> 24);
}
memset (ctx, 0, sizeof (RMD160_CTX)); /* In case it's sensitive */
}
void RMD160Data(const unsigned char *buf, unsigned int len, char *out) {
RMD160_CTX ctx;
RMD160Init(&ctx);
RMD160Update(&ctx,(unsigned char *)buf,len);
RMD160Final((unsigned char *)out,&ctx);
}

41
rmd160/rmd160.h Normal file
View File

@@ -0,0 +1,41 @@
/* RMD160.H - header file for RMD160.C
*/
#ifndef _RMD160_H_
#define _RMD160_H_
#include <sys/types.h>
#define RMD160_BLOCKBYTES 64
#define RMD160_BLOCKWORDS 16
#define RMD160_HASHBYTES 20
#define RMD160_HASHWORDS 5
/* For compatibility */
#define RIPEMD160_BLOCKBYTES 64
#define RIPEMD160_BLOCKWORDS 16
#define RIPEMD160_HASHBYTES 20
#define RIPEMD160_HASHWORDS 5
/* RIPEMD160 context. */
typedef struct RMD160Context {
u_int32_t key[RIPEMD160_BLOCKWORDS];
u_int32_t iv[RIPEMD160_HASHWORDS];
u_int32_t bytesHi, bytesLo;
} RMD160_CTX;
#define RIPEMD160Context RMD160Context
#include <sys/cdefs.h>
__BEGIN_DECLS
void RMD160Init(RMD160_CTX *);
void RMD160Update(RMD160_CTX *, const unsigned char *, unsigned int);
void RMD160Final(unsigned char [RMD160_HASHBYTES], RMD160_CTX *);
char * RMD160End(RMD160_CTX *, char *);
char * RMD160File(const char *, char *);
void RMD160Data(const unsigned char *, unsigned int, char *);
__END_DECLS
#endif /* _RMD160_H_ */

142
sha256/sha256.c Normal file
View File

@@ -0,0 +1,142 @@
/*
SHA256 implementation, source file.
This implementation was written by Kent "ethereal" Williams-King and is
hereby released into the public domain. Do what you wish with it.
No guarantees as to the correctness of the implementation are provided.
*/
#include <stdint.h>
#include <string.h>
const uint32_t sha256_initial_h[8]
= { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
const uint32_t sha256_round_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 };
void sha256_endian_reverse64(uint64_t input, uint8_t *output) {
output[7] = (input >> 0) & 0xff;
output[6] = (input >> 8) & 0xff;
output[5] = (input >> 16) & 0xff;
output[4] = (input >> 24) & 0xff;
output[3] = (input >> 32) & 0xff;
output[2] = (input >> 40) & 0xff;
output[1] = (input >> 48) & 0xff;
output[0] = (input >> 56) & 0xff;
}
uint32_t sha256_endian_read32(uint8_t *input) {
uint32_t output = 0;
output |= (input[0] << 24);
output |= (input[1] << 16);
output |= (input[2] << 8);
output |= (input[3] << 0);
return output;
}
void sha256_endian_reverse32(uint32_t input, uint8_t *output) {
output[3] = (input >> 0) & 0xff;
output[2] = (input >> 8) & 0xff;
output[1] = (input >> 16) & 0xff;
output[0] = (input >> 24) & 0xff;
}
uint32_t sha256_ror(uint32_t input, uint32_t by) {
return (input >> by) | (((input & ((1 << by) - 1))) << (32 - by));
}
void sha256(const void *data, uint64_t len, void *output) {
uint8_t padding[80];
uint64_t current = (len + 1) % 64;
// want to be == 56 % 64.
uint64_t needed = (64 + 56 - current) % 64;
uint64_t extra = needed + 9;
uint64_t total = len + extra;
for(int i = 1; i < 80; i++)
padding[i] = 0;
padding[0] = 0x80;
sha256_endian_reverse64(len * 8, padding + total - len - 8);
uint32_t v[8];
for(int i = 0; i < 8; i++)
v[i] = sha256_initial_h[i];
for(uint64_t cursor = 0; cursor * 64 < total; cursor++) {
uint32_t t[8];
for(int i = 0; i < 8; i++)
t[i] = v[i];
uint32_t w[64];
if(cursor * 64 + 64 <= len) {
for(int j = 0; j < 16; j++) {
w[j] = sha256_endian_read32(
(uint8_t *)data + cursor * 64 + j * 4);
}
}
else {
if(cursor * 64 < len) {
uint64_t size = len - cursor * 64;
if(size > 0) memcpy(w, (uint8_t *)data + cursor * 64, size);
memcpy((uint8_t *)w + size, padding, 64 - size);
}
else {
uint64_t off = (cursor * 64 - len) % 64;
memcpy((uint8_t *)w, padding + off, 64);
}
for(int j = 0; j < 16; j++) {
w[j] = sha256_endian_read32((uint8_t *)&w[j]);
}
}
for(int j = 16; j < 64; j++) {
uint32_t s1 = sha256_ror(w[j - 2], 17) ^ sha256_ror(w[j - 2], 19)
^ (w[j - 2] >> 10);
uint32_t s0 = sha256_ror(w[j - 15], 7) ^ sha256_ror(w[j - 15], 18)
^ (w[j - 15] >> 3);
w[j] = s1 + w[j - 7] + s0 + w[j - 16];
}
for(int j = 0; j < 64; j++) {
uint32_t ch = (t[4] & t[5]) ^ (~t[4] & t[6]);
uint32_t maj = (t[0] & t[1]) ^ (t[0] & t[2]) ^ (t[1] & t[2]);
uint32_t S0 = sha256_ror(t[0], 2) ^ sha256_ror(t[0], 13)
^ sha256_ror(t[0], 22);
uint32_t S1 = sha256_ror(t[4], 6) ^ sha256_ror(t[4], 11)
^ sha256_ror(t[4], 25);
uint32_t t1 = t[7] + S1 + ch + sha256_round_k[j] + w[j];
uint32_t t2 = S0 + maj;
t[7] = t[6];
t[6] = t[5];
t[5] = t[4];
t[4] = t[3] + t1;
t[3] = t[2];
t[2] = t[1];
t[1] = t[0];
t[0] = t1 + t2;
}
for(int i = 0; i < 8; i++)
v[i] += t[i];
}
for(int i = 0; i < 8; i++)
sha256_endian_reverse32(v[i], (uint8_t *)output + i * 4);
}

17
sha256/sha256.h Normal file
View File

@@ -0,0 +1,17 @@
/*
SHA256 implementation, header file.
This implementation was written by Kent "ethereal" Williams-King and is
hereby released into the public domain. Do what you wish with it.
No guarantees as to the correctness of the implementation are provided.
*/
#ifndef SHA256_H
#define SHA256_H
#include <stdint.h>
void sha256(const void *data, uint64_t len, void *output);
#endif

186
util.h Normal file
View File

@@ -0,0 +1,186 @@
typedef struct str_list {
int n;
char **data;
int *lengths;
}List;
typedef struct str_tokenizer {
int current;
int n;
char **tokens;
}Tokenizer;
char *ltrim(char *str, const char *seps);
char *rtrim(char *str, const char *seps);
char *trim(char *str, const char *seps);
int indexOf(char *s,const char **array,int length_array);
int hexchr2bin(char hex, char *out);
int hexs2bin(char *hex, unsigned char *out);
char *tohex(char *ptr,int length);
int hasMoreTokens(Tokenizer *t);
char *nextToken(Tokenizer *t);
char *ltrim(char *str, const char *seps) {
size_t totrim;
if (seps == NULL) {
seps = "\t\n\v\f\r ";
}
totrim = strspn(str, seps);
if (totrim > 0) {
size_t len = strlen(str);
if (totrim == len) {
str[0] = '\0';
}
else {
memmove(str, str + totrim, len + 1 - totrim);
}
}
return str;
}
char *rtrim(char *str, const char *seps) {
int i;
if (seps == NULL) {
seps = "\t\n\v\f\r ";
}
i = strlen(str) - 1;
while (i >= 0 && strchr(seps, str[i]) != NULL) {
str[i] = '\0';
i--;
}
return str;
}
char *trim(char *str, const char *seps) {
return ltrim(rtrim(str, seps), seps);
}
int indexOf(char *s,const char **array,int length_array) {
int index = -1,i,continuar = 1;
for(i = 0; i <length_array && continuar; i++) {
if(strcmp(s,array[i]) == 0) {
index = i;
continuar = 0;
}
}
return index;
}
char *nextToken(Tokenizer *t) {
if(t->current < t->n) {
t->current++;
return t->tokens[t->current-1];
}
else {
return NULL;
}
}
int hasMoreTokens(Tokenizer *t) {
return (t->current < t->n);
}
void stringtokenizer(char *data,Tokenizer *t) {
char *token;
t->tokens = NULL;
t->n = 0;
t->current = 0;
trim(data,"\t\n\r ");
token = strtok(data," \t:");
while(token != NULL) {
t->n++;
t->tokens = realloc(t->tokens,sizeof(char*)*t->n);
if(t->tokens == NULL) {
printf("Out of memory\n");
exit(0);
}
t->tokens[t->n - 1] = token;
token = strtok(NULL," \t");
}
}
void freetokenizer(Tokenizer *t) {
if(t->n > 0) {
free(t-> tokens);
}
memset(t,0,sizeof(Tokenizer));
}
/*
Aux function to get the hexvalues of the data
*/
char *tohex(char *ptr,int length){
char *buffer;
int offset = 0;
unsigned char c;
buffer = (char *) malloc((length * 2)+1);
for (int i = 0; i <length; i++) {
c = ptr[i];
sprintf((char*) (buffer + offset),"%.2x",c);
offset+=2;
}
buffer[length*2] = 0;
return buffer;
}
int hexs2bin(char *hex, unsigned char *out) {
int len;
char b1;
char b2;
int i;
if (hex == NULL || *hex == '\0' || out == NULL)
return 0;
len = strlen(hex);
if (len % 2 != 0)
return 0;
len /= 2;
memset(out, 'A', len);
for (i=0; i<len; i++) {
if (!hexchr2bin(hex[i*2], &b1) || !hexchr2bin(hex[i*2+1], &b2)) {
return 0;
}
out[i] = (b1 << 4) | b2;
}
return len;
}
int hexchr2bin(const char hex, char *out) {
if (out == NULL)
return 0;
if (hex >= '0' && hex <= '9') {
*out = hex - '0';
} else if (hex >= 'A' && hex <= 'F') {
*out = hex - 'A' + 10;
} else if (hex >= 'a' && hex <= 'f') {
*out = hex - 'a' + 10;
} else {
return 0;
}
return 1;
}
void addItemList(char *data, List *l) {
l->data = realloc(l->data,sizeof(char*)* (l->n +1));
l->data[l->n] = data;
l->n++;
}
int isValidHex(char *data) {
char c;
int len,i,valid = 1;
len = strlen(data);
for(i = 0 ; i < len && valid ;i++ ) {
c = data[i];
valid = ( (c >= '0' && c <='9') || (c >= 'A' && c <='F' ) || (c >= 'a' && c <='f' ) );
}
return valid;
}