Created
September 30, 2014 03:42
-
-
Save eminence/0b4c49551616b442e3da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <memory.h> | |
#include <string.h> | |
#include <stdbool.h> | |
struct BITS8_TYPE{ | |
unsigned b0:1; | |
unsigned b1:1; | |
unsigned b2:1; | |
unsigned b3:1; | |
unsigned b4:1; | |
unsigned b5:1; | |
unsigned b6:1; | |
unsigned b7:1; | |
} Bits8_Type; | |
#define MAX_EXC_SEGMENT_LENGTH 65536 | |
#define MAX_EXC_BLOCK_LENGTH 256 | |
#define MAX_EXC_BLOCKS 256 // MAX_EXC_SEGMENT_LENGTH / MAX_EXC_BLOCK_LENGTH | |
#define MAX_EXC_LIST_LENGTH 85 // MAX_EXC_BLOCK_LENGTH / 3 | |
#define MIN_EXC_LIST_LENGTH 2 // 1 Byte for block number, 1 Byte for list length | |
#define MAX_EXC_BLOCK_ENTRIES 63 // bits 0-5 values 0-63 | |
struct EXC_SEG_ENTRY_TYPE{ | |
long offset; | |
long length; | |
char list[MAX_EXC_LIST_LENGTH]; | |
} Exc_Seg_Entry_Type; | |
struct EXC_SEG_TYPE{ | |
long profit; | |
long blocks; | |
long seed_size; | |
long seed; | |
struct EXC_SEG_ENTRY_TYPE block[MAX_EXC_BLOCKS]; | |
} Exc_Seg_Type; | |
long bin2exc(char *buffer, long size, char *output, long *length, struct EXC_SEG_TYPE *exc); | |
long excscan(char *buffer, long size, char *output, struct EXC_SEG_TYPE *exc); | |
long recombin(char *buffer, long size, char *output, long seed); | |
long exc2bin(char *buffer, long size, char *output, long *length); | |
long decombin(char *buffer, long size, char *output, long seed); | |
long recombin(char *buffer, long size, char *output, long seed){ | |
long Cur_Pos = 0; | |
char Cur_Chr = 0; | |
char Rnd_Chr = 0; | |
long Cur_Val = 0; | |
char Out_Chr = 0; | |
char Inp_Buf[MAX_EXC_SEGMENT_LENGTH]; | |
memset(Inp_Buf, 0, MAX_EXC_SEGMENT_LENGTH); | |
// validate arguments | |
if(buffer < 1) return -1; | |
if(size > MAX_EXC_SEGMENT_LENGTH) return -1; | |
if(size < 1) return -1; | |
if(output < NULL) return -1; | |
// combine buffer data with random data and send it to the output buffer | |
srand((unsigned int)seed); | |
for(Cur_Pos = 0; Cur_Pos < size; Cur_Pos++){ | |
Cur_Chr = buffer[Cur_Pos]; | |
Rnd_Chr = (char)(rand() % 255); | |
Cur_Val = Cur_Chr + Rnd_Chr; | |
Out_Chr = (char)(Cur_Val - (256 * (long)((Cur_Val + 0.1) / 256))); | |
output[Cur_Pos] = Out_Chr; | |
} | |
return 0; | |
} | |
long excscan(char *buffer, long size, char *output, struct EXC_SEG_TYPE *exc){ | |
long Cur_Ret = 0; | |
long Cur_Pos = 0; | |
long Len_Blk = 0; | |
long Cur_Blk = 0; | |
long Seg_Pos = 0; | |
long Inp_Pos = 0; | |
char Cur_Buf[MAX_EXC_SEGMENT_LENGTH]; | |
memset(Cur_Buf, 0, MAX_EXC_SEGMENT_LENGTH); | |
// validate arguments | |
if(buffer < 1) return -1; | |
if(size > MAX_EXC_SEGMENT_LENGTH) return -1; | |
if(size < 1) return -1; | |
if(output < NULL) return -1; | |
if(exc < NULL) return -1; | |
// validate the size of the seed value | |
exc->seed_size = 1; | |
if(exc->seed > 255) exc->seed_size = 2; | |
if(exc->seed > 65535) exc->seed_size = 4; | |
if(exc->seed > 4294967295) return -1; | |
// reset the segment cycle | |
exc->blocks = 0; | |
exc->profit = 0; | |
Len_Blk = MAX_EXC_BLOCK_LENGTH; | |
// recombine the segment data with newly seeded random data | |
Cur_Ret = recombin(buffer, size, Cur_Buf, exc->seed); if(Cur_Ret < 0) return Cur_Ret; | |
// scan the recombined segment data | |
while(Seg_Pos < size){ | |
// validate the block length | |
if((size - Seg_Pos) < MAX_EXC_BLOCK_LENGTH) Len_Blk = size - Seg_Pos; | |
if(Len_Blk < 3) break; | |
// reset the block entry | |
exc->block[exc->blocks].offset = Cur_Blk; | |
exc->block[exc->blocks].length = 0; | |
// scan the block for trio groups | |
for(Cur_Pos = 0; Cur_Pos < (Len_Blk - 2); Cur_Pos++){ | |
// add the trio position to the block list | |
if(Cur_Buf[Inp_Pos] == Cur_Buf[Inp_Pos + 1] && Cur_Buf[Inp_Pos + 1] == Cur_Buf[Inp_Pos + 2]){ | |
exc->block[exc->blocks].list[exc->block[exc->blocks].length] = (char)Cur_Pos; | |
exc->block[exc->blocks].length++; | |
Cur_Pos += 2; | |
Inp_Pos += 2; | |
} | |
Inp_Pos++; | |
} | |
// add the block if there is enough trio groups for a profit | |
if(exc->block[exc->blocks].length > MIN_EXC_LIST_LENGTH){ | |
exc->profit += (exc->block[exc->blocks].length - MIN_EXC_LIST_LENGTH); | |
if(exc->blocks > MAX_EXC_BLOCK_ENTRIES) break; | |
exc->blocks++; | |
} | |
// increment the segment position | |
Cur_Blk++; | |
Seg_Pos += (Cur_Blk * MAX_EXC_BLOCK_LENGTH); | |
} | |
// set output variables | |
exc->profit -= (exc->seed_size + 1); | |
memcpy(output, Cur_Buf, size); | |
return 0; | |
} | |
long bin2exc(char *buffer, long size, char *output, long *length, struct EXC_SEG_TYPE *exc){ | |
char Chr_Val = 0; | |
short int Sin_Val = 0; | |
int Int_Val = 0; | |
long Lng_Val = 0; | |
long Cur_Pos = 0; | |
long Cur_Blk = 0; | |
long Ofs_Pos = 0; | |
long Out_Pos = 0; | |
long Ofs_Num = 0; | |
long Lst_Pos = 0; | |
bool Tog_End = false; | |
char *Str_Val = NULL; | |
struct BITS8_TYPE Bit_Chr; | |
char *Out_Chr = NULL; | |
// validate arguments | |
if(buffer < 1) return -1; | |
if(size > MAX_EXC_SEGMENT_LENGTH) return -1; | |
if(size < 1) return -1; | |
if(output < NULL) return -1; | |
if(length < NULL) return -1; | |
if(exc < NULL) return -1; | |
// set block count bits | |
Bit_Chr.b0 = (exc->blocks & 1); | |
Bit_Chr.b1 = (exc->blocks & 2); | |
Bit_Chr.b2 = (exc->blocks & 4); | |
Bit_Chr.b3 = (exc->blocks & 8); | |
Bit_Chr.b4 = (exc->blocks & 16); | |
Bit_Chr.b5 = (exc->blocks & 32); | |
// set seed size bits | |
Bit_Chr.b6 = (exc->seed_size & 1); | |
Bit_Chr.b7 = (exc->seed_size & 2); | |
// set the segment data byte | |
Out_Chr = (char *)&Bit_Chr; | |
output[0] = *Out_Chr; | |
Out_Pos++; | |
// set the seed bytes | |
if(exc->seed_size == (long)sizeof(Chr_Val)){Chr_Val = (char)exc->seed; Str_Val = (char *)&Chr_Val;} | |
if(exc->seed_size == (long)sizeof(Sin_Val)){Sin_Val = (short int)exc->seed; Str_Val = (char *)&Sin_Val;} | |
if(exc->seed_size == (long)sizeof(Int_Val)){Int_Val = (int)exc->seed; Str_Val = (char *)&Int_Val;} | |
if(exc->seed_size == (long)sizeof(Lng_Val)){Lng_Val = (long)exc->seed; Str_Val = (char *)&Lng_Val;} | |
memcpy(output + Out_Pos, Str_Val, exc->seed_size); | |
Out_Pos += exc->seed_size; | |
// copy all the block entries | |
for(Cur_Blk = 0; Cur_Blk < exc->blocks; Cur_Blk++){ | |
output[Out_Pos] = (char)exc->block[Cur_Blk].offset; Out_Pos++; | |
output[Out_Pos] = (char)exc->block[Cur_Blk].length; Out_Pos++; | |
memcpy(output + Out_Pos, exc->block[Cur_Blk].list, exc->block[Cur_Blk].length); Out_Pos += exc->block[Cur_Blk].length; | |
} | |
// copy the data without block references | |
Cur_Blk = 0; Lst_Pos = 0; Ofs_Pos = 0; Ofs_Num = 0; Tog_End = false; | |
for(Cur_Pos = 0; Cur_Pos < size; Cur_Pos++){ | |
// copy the current byte | |
output[Out_Pos] = buffer[Cur_Pos]; Out_Pos++; | |
// check for a block entry | |
if(Tog_End == false){ | |
// check for correct block offset and list position | |
if(Ofs_Num == exc->block[Cur_Blk].offset && Ofs_Pos == (long)exc->block[Cur_Blk].list[Lst_Pos]){ | |
// increment buffer and list position | |
Cur_Pos += 2; | |
Lst_Pos++; | |
// increment block number | |
if(Lst_Pos >= exc->block[Cur_Blk].length){ | |
Cur_Blk++; | |
Lst_Pos = 0; | |
if(Cur_Blk >= exc->blocks) Tog_End = true; | |
} | |
} | |
} | |
// increment offset position and number | |
Ofs_Pos++; | |
if(Ofs_Pos > 255){Ofs_Pos = 0; Ofs_Num++;} | |
} | |
*length = Out_Pos; | |
return 0; | |
} | |
long decombin(char *buffer, long size, char *output, long seed){ | |
return 0; | |
} | |
long exc2bin(char *buffer, long size, char *output, long *length){ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment