Compare commits
6 Commits
0318221f3f
...
vector_sor
Author | SHA1 | Date | |
---|---|---|---|
04e4d07e99 | |||
a99d1d3784 | |||
7fae216ccf | |||
89a3585c7f | |||
c81c8bfa3c | |||
e622107f07 |
@ -1,9 +1,6 @@
|
||||
---
|
||||
name: Test and Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@ -29,6 +26,7 @@ jobs:
|
||||
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
if: gitea.ref == 'refs/heads/master'
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
@ -2,6 +2,9 @@
|
||||
|
||||
Cryptographic tools
|
||||
|
||||
Any functions that return string representations of bytes in hexadecimal format will
|
||||
always be formatted with no leading `0x` and lower case letters
|
||||
|
||||
## Functions
|
||||
|
||||
### b64_encode
|
||||
@ -26,22 +29,25 @@ unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz);
|
||||
### hex_encode
|
||||
|
||||
Encodes an array of bytes into a string in hex representation. For example, converts
|
||||
`[0xDE, 0xAD, 0xBE, 0xEF]` into `"DEADBEEF"`. The returned string will always be in capital
|
||||
letters with no leading `0x`. User is responsible for the freeing of the returned string
|
||||
`[0xDE, 0xAD, 0xBE, 0xEF]` into `"deadbeef"`. User is responsible for freeing the returned string
|
||||
|
||||
```c
|
||||
const char *hex_encode(const unsigned char *hex, size_t sz);
|
||||
|
||||
// Example
|
||||
unsigned char h[4] = {
|
||||
0xde, 0xad, 0xbe, 0xef
|
||||
};
|
||||
const char *s = hex_encode(h, 4);
|
||||
assert(strcmp(s, "DEADBEEF") == 0);
|
||||
assert(strcmp(s, "deadbeef") == 0);
|
||||
free(s);
|
||||
```
|
||||
|
||||
### hex_decode
|
||||
|
||||
Decodes a string of characters representing hexadecimal bytes into an array of `unsigned char`.
|
||||
For example, converts `"DEADBEEF"` into `[0xDE, 0xAD, 0xBE, 0xEF]`. User is reponsible for the
|
||||
Characters can be in upper or lower case, and can start with a leading `0x` or not.
|
||||
For example, converts `"DEADBEEF"` into `[0xde, 0xad, 0xbe, 0xef]`. User is reponsible for the
|
||||
freeing of the returned byte array
|
||||
|
||||
```c
|
||||
@ -83,3 +89,19 @@ responsible for freeing the returned array
|
||||
```c
|
||||
const unsigned char *repeating_key_xor_s(const char* s, const char* key);
|
||||
```
|
||||
|
||||
### hamming_distance
|
||||
|
||||
Calculates the Hamming Distance (the number of differing bits) between two arrays of unsigned bytes
|
||||
|
||||
```c
|
||||
unsigned int hamming_distance(unsigned char *a, unsigned char *b);
|
||||
```
|
||||
|
||||
### hamming_distance_s
|
||||
|
||||
Calculates the Hamming Distance (the number of differing bits) between two strings
|
||||
|
||||
```c
|
||||
unsigned int hamming_distance_s(const char *a, const char *b);
|
||||
```
|
||||
|
@ -61,3 +61,12 @@ for (int i = 0; i < 10; i++) {
|
||||
}
|
||||
free(pd);
|
||||
```
|
||||
|
||||
## reallocarray
|
||||
|
||||
reallocarray is reimplemented for macOS because Apple doesn't expose their implementation. This is taken straight
|
||||
from the OpenBSD source
|
||||
|
||||
```c
|
||||
void *reallocarray(void *optr, size_t nmemb, size_t size);
|
||||
```
|
||||
|
15
docs/math.md
15
docs/math.md
@ -57,3 +57,18 @@ Works the same as `bresenham()` but uses the `Point` struct instead of `int`
|
||||
```c
|
||||
Point *bresenham_p(Point p1, Point p2, size_t *sz);
|
||||
```
|
||||
|
||||
## Comparison Functions
|
||||
|
||||
Comparison functions to compare two items. These functions must return `1` if `a > b`, `-1` if
|
||||
`a < b`, or `0` if `a == b`. This follows the pattern defined by `compar` functions in the C standard
|
||||
library, making these usuable in the standard sorting functions like `qsort`
|
||||
|
||||
```c
|
||||
int compar_int(const void *a, const void *b);
|
||||
int compar_char(const void *a, const void *b);
|
||||
|
||||
// Example
|
||||
qsort(arr, arr_sz, sizeof(int), compar_int);
|
||||
```
|
||||
|
||||
|
@ -137,16 +137,6 @@ comparison function to compare the data in the vector. This function must return
|
||||
const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b));
|
||||
```
|
||||
|
||||
## Comparison Functions
|
||||
|
||||
Comparison functions to compare data in a vector. These functions must return `1` if `a > b`, `-1` if
|
||||
`a < b`, or `0` if `a == b`.
|
||||
|
||||
```c
|
||||
int vec_cmp_int(const void *a, const void *b);
|
||||
int vec_cmp_char(const void *a, const void *b);
|
||||
```
|
||||
|
||||
## Macros
|
||||
|
||||
### vec_at
|
||||
|
@ -13,4 +13,7 @@ const char *hex_to_str(const unsigned char *hex, size_t sz);
|
||||
const unsigned char* repeating_key_xor(const unsigned char* s, size_t s_sz, const unsigned char* key, size_t k_sz);
|
||||
const unsigned char *repeating_key_xor_s(const char* s, const char* key);
|
||||
|
||||
unsigned int hamming_distance_s(const char *a, const char *b);
|
||||
unsigned int hamming_distance(unsigned char *a, unsigned char *b, size_t sz);
|
||||
|
||||
#endif // LIBFLINT_CRYPTO_H
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct {
|
||||
double total_user_time;
|
||||
double total_kernel_time;
|
||||
@ -18,6 +20,7 @@ typedef struct {
|
||||
|
||||
ProcessData *new_ProcessData();
|
||||
int update_process(pid_t pid, ProcessData *proc);
|
||||
void *reallocarray(void *optr, size_t nmemb, size_t size);
|
||||
|
||||
#endif /* defined(__APPLE__) || defined(__MACH__) */
|
||||
#endif /* LIBFLINT_MACOS_H */
|
||||
|
@ -15,4 +15,9 @@ Point *bresenham(int x0, int y0, int x1, int y1, size_t *sz);
|
||||
|
||||
Point *bresenham_p(Point p1, Point p2, size_t *sz);
|
||||
|
||||
int compar_int(const void *a, const void *b);
|
||||
|
||||
int compar_char(const void *a, const void *b);
|
||||
|
||||
|
||||
#endif // LIBFLINT_H_MATH
|
||||
|
@ -30,9 +30,7 @@ const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b));
|
||||
|
||||
const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b));
|
||||
|
||||
int vec_cmp_int(const void *a, const void *b);
|
||||
|
||||
int vec_cmp_char(const void *a, const void *b);
|
||||
int vec_sort(Vector *vec, int(*cmp)(const void *a, const void *b));
|
||||
|
||||
#define vec_at(v, i) (v)->elements[(i)]
|
||||
|
||||
|
38
src/crypto.c
38
src/crypto.c
@ -204,16 +204,22 @@ unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz) {
|
||||
|
||||
unsigned char *hex_decode(const char *orig, size_t *sz) {
|
||||
size_t buf_sz = strlen(orig) + 1;
|
||||
char *sptr = orig;
|
||||
if (strncmp(orig, "0x", 2) == 0) {
|
||||
buf_sz -= 2;
|
||||
sptr += 2;
|
||||
}
|
||||
|
||||
if (strlen(orig) % 2 != 0) {
|
||||
buf_sz += 1;
|
||||
}
|
||||
|
||||
char *buf = malloc(sizeof(char) * buf_sz);
|
||||
if (strlen(orig) % 2 != 0) {
|
||||
strcpy(buf + 1, orig);
|
||||
if (strlen(sptr) % 2 != 0) {
|
||||
strcpy(buf+ 1, sptr);
|
||||
buf[0] = '0';
|
||||
} else {
|
||||
strcpy(buf, orig);
|
||||
strcpy(buf, sptr);
|
||||
}
|
||||
buf[buf_sz - 1] = '\0';
|
||||
|
||||
@ -265,3 +271,29 @@ const unsigned char* repeating_key_xor(const unsigned char* s, size_t s_sz, cons
|
||||
const unsigned char *repeating_key_xor_s(const char* s, const char* key) {
|
||||
return repeating_key_xor((unsigned char*)s, strlen(s), (unsigned char*)key, strlen(key));
|
||||
}
|
||||
|
||||
unsigned int hamming_distance_s(const char *a, const char *b) {
|
||||
size_t sz = strlen(a);
|
||||
if (sz != strlen(b)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hamming_distance((unsigned char *)a, (unsigned char *)b, sz);
|
||||
}
|
||||
|
||||
unsigned int hamming_distance(unsigned char *a, unsigned char *b, size_t sz) {
|
||||
unsigned int hamming = 0;
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
if (a[i] == b[i]) {
|
||||
continue;
|
||||
}
|
||||
unsigned char c = a[i] ^ b[i];
|
||||
unsigned int count = 0;
|
||||
for (; c; count++) {
|
||||
c &= c - 1;
|
||||
}
|
||||
hamming += count;
|
||||
}
|
||||
|
||||
return hamming;
|
||||
}
|
||||
|
37
src/macos.c
37
src/macos.c
@ -1,6 +1,7 @@
|
||||
#include <libproc.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lfmacos.h"
|
||||
@ -43,3 +44,39 @@ int update_process(pid_t pid, ProcessData *proc) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reallocarray is reimplemented here for macOS because Apple doesn't expose
|
||||
* their implementation. This is taken straight from the OpenBSD source as
|
||||
* shown in the below copyright notice
|
||||
*/
|
||||
|
||||
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/stdlib/reallocarray.c */
|
||||
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
void *reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
||||
|
@ -77,3 +77,11 @@ Point *bresenham_p(Point p1, Point p2, size_t *sz) {
|
||||
return bresenham(p1.x, p1.y, p2.x, p2.y, sz);
|
||||
}
|
||||
|
||||
|
||||
int compar_int(const void *a, const void *b) {
|
||||
return (*(int*)a - *(int*)b);
|
||||
}
|
||||
|
||||
int compar_char(const void *a, const void *b) {
|
||||
return (*(char*)a - *(char*)b);
|
||||
}
|
||||
|
46
src/vector.c
46
src/vector.c
@ -5,6 +5,10 @@
|
||||
#include <bsd/stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
#include "lfmacos.h"
|
||||
#endif
|
||||
|
||||
#include "lfvector.h"
|
||||
|
||||
#define VEC_INIT_CAP 2
|
||||
@ -31,13 +35,7 @@ int vec_init_with_capacity(Vector *vec, void (*destroy)(void *data), size_t capa
|
||||
|
||||
static int vec_grow(Vector *const vec) {
|
||||
vec->capacity *= 2;
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
vec->elements = reallocarray(vec->elements, vec->capacity, sizeof(void *));
|
||||
#else
|
||||
vec->elements = reallocf(vec->elements, sizeof(void *) * vec->capacity);
|
||||
#endif
|
||||
|
||||
if (vec->elements == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -110,19 +108,11 @@ int vec_shrink(Vector *vec) {
|
||||
if (vec_len(vec) == vec_cap(vec)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->capacity = vec_len(vec);
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
vec->elements = reallocarray(vec->elements, vec->capacity, sizeof(void *));
|
||||
#else
|
||||
vec->elements = reallocf(vec->elements, sizeof(void *) * vec->capacity);
|
||||
#endif
|
||||
|
||||
if (vec->elements == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -146,28 +136,10 @@ const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b))
|
||||
return a;
|
||||
}
|
||||
|
||||
int vec_cmp_int(const void *a, const void *b) {
|
||||
const int x = *(int*)a;
|
||||
const int y = *(int*)b;
|
||||
|
||||
if (x > y) {
|
||||
return 1;
|
||||
int vec_sort(Vector *vec, int(*cmp)(const void *a, const void *b)) {
|
||||
if (vec_len(vec) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x < y) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vec_cmp_char(const void *a, const void *b) {
|
||||
const char x = *(int*)a;
|
||||
const char y = *(int*)b;
|
||||
|
||||
if (x > y) {
|
||||
return 1;
|
||||
}
|
||||
if (x < y) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
qsort(vec->elements, vec->length, sizeof(void *), cmp);
|
||||
return 1;
|
||||
}
|
||||
|
@ -239,8 +239,8 @@ void test_vector() {
|
||||
t = (int*)vec_at(v, 4);
|
||||
assert(*t == e4);
|
||||
|
||||
const int *min = vec_min(v, vec_cmp_int);
|
||||
const int *max = vec_max(v, vec_cmp_int);
|
||||
const int *min = vec_min(v, compar_int);
|
||||
const int *max = vec_max(v, compar_int);
|
||||
printf("min: %d\n", *min);
|
||||
printf("max: %d\n", *max);
|
||||
assert(*min == e0);
|
||||
@ -260,6 +260,19 @@ void test_vector() {
|
||||
assert(vec_len(v) == vec_cap(v));
|
||||
printf("cap after shrink: %zu\n", vec_cap(v));
|
||||
|
||||
int s1 = 10;
|
||||
int s2 = 2;
|
||||
int s3 = 1;
|
||||
vec_push(v, &s1);
|
||||
vec_push(v, &s2);
|
||||
vec_push(v, &s3);
|
||||
|
||||
printf("Before sort: ");
|
||||
print_vector(v);
|
||||
vec_sort(v, compar_int);
|
||||
printf("After sort: ");
|
||||
print_vector(v);
|
||||
|
||||
vec_destroy(v);
|
||||
free(v);
|
||||
}
|
||||
@ -349,6 +362,13 @@ void test_crypto() {
|
||||
}
|
||||
free(s);
|
||||
|
||||
// leading 0x
|
||||
s = hex_decode("0xf00f5", &s_sz);
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
assert(s[i] == h2[i]);
|
||||
}
|
||||
free(s);
|
||||
|
||||
s = hex_encode(h, 4);
|
||||
assert(strcmp(s, "deadbeef") == 0);
|
||||
free(s);
|
||||
@ -367,6 +387,14 @@ void test_crypto() {
|
||||
free(enc);
|
||||
free(s);
|
||||
|
||||
unsigned char ua[2] = { 0x2, 0xF };
|
||||
unsigned char ub[2] = { 0x4, 0xE };
|
||||
unsigned int hamming = hamming_distance(ua, ub, 2);
|
||||
assert(hamming == 3);
|
||||
|
||||
hamming = hamming_distance_s("this is a test", "wokka wokka!!!");
|
||||
assert(hamming == 37);
|
||||
|
||||
printf("Passes all crypto tests\n");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user