Skip to content

Instantly share code, notes, and snippets.

@eminence
Created September 30, 2014 03:42
Show Gist options
  • Save eminence/0b4c49551616b442e3da to your computer and use it in GitHub Desktop.
Save eminence/0b4c49551616b442e3da to your computer and use it in GitHub Desktop.
#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