I am using Okamura's implementation of lzss : https://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c
int enc_i = 0;
int getbit(int n, unsigned char *enco_buf) /* get n bits */
{
int i, x;
static int buf, mask = 0;
x = 0;
for (i = 0; i < n; i++) {
if (mask == 0) {
//if ((buf = fgetc(infile)) == EOF) return EOF;
//if ((buf = fgetc(infile)) == EOF) return EOF;
if((buf = enco_buf[enc_i]) == '\0') break;
//buf = enco_buf[enc_i];
enc_i++;
//printf("\nValue of enc : %d\n", enc_i);
mask = 128;
}
x <<= 1;
if (buf & mask) x++;
mask >>= 1;
}
return x;
}
void decode(unsigned char *enco_buf)
{
int i, j, k, r, c;
outfile = fopen ("test_lib.txt", "wb");
for (i = 0; i < N - F; i++) buffer[i] = ' ';
r = N - F;
while ((c = getbit(1, enco_buf)) != '\0') {
if (c) {
if ((c = getbit(8, enco_buf)) == '\0') break;
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
} else {
if ((i = getbit(EI, enco_buf)) == '\0') break;
if ((j = getbit(EJ, enco_buf)) == '\0') break;
for (k = 0; k <= j + 1; k++) {
c = buffer[(i + k) & (N - 1)];
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
}
}
}
fclose(outfile);
}
Rather than taking the input from file, I am taking an encoded buffer which I am passing to the function decode() which in-turns passes to getbit(). But it is decoding upto a certain number of bits ie. 43. What I am guessing is I put '\0' instead of EOF (as it was in file end marker) to detect string end. and that might be the problem where break statement is executed finding '\0'. It might not be true but It might be the case. The encoding part has no problem as I verified it with the original code. Can anyone suggest where might be the problem?
EDIT : source code:
/* LZSS encoder-decoder (Haruhiko Okumura; public domain) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lzss_lib.h"
#define EI 11 /* typically 10..13 */
#define EJ 4 /* typically 4..5 */
#define P 1 /* If match length <= P then output one character */
#define N (1 << EI) /* buffer size */
#define F ((1 << EJ) + 1) /* lookahead buffer size */
int bit_buffer = 0, bit_mask = 128;
unsigned long codecount = 0, textcount = 0;
unsigned char buffer[N * 2];
int payload_i = 0;
int enc_i = 0;
FILE *infile, *outfile;
void error(void)
{
printf("Output error\n"); exit(1);
}
void putbit1(unsigned char *put_buf0)
{
bit_buffer |= bit_mask;
if ((bit_mask >>= 1) == 0) {
put_buf0[payload_i] = bit_buffer;
payload_i++;
bit_buffer = 0; bit_mask = 128; codecount++;
}
}
void putbit0(unsigned char *put_buf1)
{
if ((bit_mask >>= 1) == 0) {
put_buf1[payload_i] = bit_buffer;
payload_i++;
bit_buffer = 0; bit_mask = 128; codecount++;
}
}
void flush_bit_buffer(unsigned char *flush_bit)
{
if (bit_mask != 128) {
flush_bit[payload_i] = bit_buffer;
codecount++;
}
}
void output1(int c, unsigned char *buf_output1)
{
int mask;
putbit1(buf_output1);
mask = 256;
while (mask >>= 1) {
if (c & mask) putbit1(buf_output1);
else putbit0(buf_output1);
}
}
void output2(int x, int y, unsigned char *buf_output2)
{
int mask;
putbit0(buf_output2);
mask = N;
while (mask >>= 1) {
if (x & mask) putbit1(buf_output2);
else putbit0(buf_output2);
}
mask = (1 << EJ);
while (mask >>= 1) {
if (y & mask) putbit1(buf_output2);
else putbit0(buf_output2);
}
}
void encode(unsigned char *string_buf, unsigned char *out_buf, unsigned long *out_buf_len)
{
int i, j, f1, x, y, r, s, bufferend, c, tt;
tt = 0;
for (i = 0; i < N - F; i++) buffer[i] = ' ';
for (i = N - F; i < N * 2; i++) {
if((c = string_buf[tt]) == '\0') break;
buffer[i] = c; textcount++; tt++;
}
bufferend = i; r = N - F; s = 0;
while (r < bufferend) {
f1 = (F <= bufferend - r) ? F : bufferend - r;
x = 0; y = 1; c = buffer[r];
for (i = r - 1; i >= s; i--)
if (buffer[i] == c) {
for (j = 1; j < f1; j++)
if (buffer[i + j] != buffer[r + j]) break;
if (j > y) {
x = i; y = j;
}
}
if (y <= P) { y = 1; output1(c, out_buf); }
else output2(x & (N - 1), y - 2, out_buf);
r += y; s += y;
if (r >= N * 2 - F) {
for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
bufferend -= N; r -= N; s -= N;
while (bufferend < N * 2) {
if((c = string_buf[tt]) == '\0') break;
buffer[bufferend++] = c; textcount++; tt++;
}
}
}
flush_bit_buffer(out_buf);
*out_buf_len = codecount;
printf("text: %ld bytes\n", textcount);
printf("code: %ld bytes (%ld%%)\n", codecount, (codecount * 100) / textcount);
}
int getbit(int n, unsigned char *enco_buf) /* get n bits */
{
int i, x;
static int buf, mask = 0;
x = 0;
for (i = 0; i < n; i++) {
if (mask == 0) {
//if ((buf = fgetc(infile)) == EOF) return EOF;
//if ((buf = fgetc(infile)) == EOF) return EOF;
if((buf = enco_buf[enc_i]) == '\0') break;
//buf = enco_buf[enc_i];
enc_i++;
printf("\nValue of enc : %d\n", enc_i);
mask = 128;
}
x <<= 1;
if (buf & mask) x++;
mask >>= 1;
}
return x;
}
void decode(unsigned char *enco_buf)
{
int i, j, k, r, c;
outfile = fopen ("test_lib.txt", "wb");
for (i = 0; i < N - F; i++) buffer[i] = ' ';
r = N - F;
while ((c = getbit(1, enco_buf)) != '\0') {
if (c) {
if ((c = getbit(8, enco_buf)) == '\0') break;
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
} else {
if ((i = getbit(EI, enco_buf)) == '\0') break;
if ((j = getbit(EJ, enco_buf)) == '\0') break;
for (k = 0; k <= j + 1; k++) {
c = buffer[(i + k) & (N - 1)];
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
}
}
}
fclose(outfile);
}
and the test example :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lzss_lib.h"
unsigned char compr_data[4096];
unsigned long pw = 0;
unsigned long payload_len = 0;
volatile int errno;
unsigned char *unc_data = "d(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):WritingModule:SecurityConfigD/6LoWPANd(2306):WritingModule:RunCoordinatorD/6LoWPANd(2306):RequestingmoduleaddressD/6LoWPANd(2306):WritingModule:GetAddressD/smartcard-jni(2781):SmartCard_state_update_callback:status=6D/SmartCardNative(2781):status=6D/smartcard(2781):PN532Smartcard_loop_threadexitD/smartcard-jni(2781):SmartCard_loop_thread:SMARTCARD_STATUS_ABORTD/smartcard(2781):Smartcard_loop_uninitD/smartcard(2781):2D/serialcomm_pn532(2781):PN532:Readingfrom/dev/ttyUSB0-->D/smartcard(2781):Received(0x3)fromPN532:(dataBuf[0]:0x1)(0x1f5988)D/smartcard(2781):ReceivedStatusfromPN532:OK(cmd:0x2)D/smartcard-jni(2781):SmartCard_listener_update_callbackD/smartcard(2781):Received(0x1c2)fromPN532:(dataBuf[0]:0x32)(0x1f5988)D/smartcard(2781):vd(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):";
FILE *outfile;
int main(void) {
memset (compr_data, '\0', sizeof(compr_data));
encode(unc_data, compr_data, &payload_len);
decode(compr_data);
return 0;
}
Related
Currently struggling to solve ex 1.21. The task is: Write a program entab that replaces strings of blanks by the minimum number
of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab . When
either a tab or a single blank would suffice to reach a tab stop, which should be given
preference?
Below is my code i have made so far. I have no problems typing the amount of spaces less than tabsize but when it is bigger than that I get segmentation fault. Could anyone help me, please?
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0)
{
int space = 0;
int pos = 0;
int count = 0;
while (line[count] != '\n')
{
if (line[count] != ' ')
{
space = 0;
output[count] = line[count];
}
else if (line[count] == ' ')
{
pos = count - space;
space++;
if (line[count + 1] != ' ')
{
if (space > TAB)
{
int z = entab(output, pos, space);
count = z;
}
else
{
for (int a = 0; a < space; a++)
output[pos + a] = ' ';
}
}
}
count++;
}
if (line[count] == '\n')
{
output[count] = line[count];
count++;
}
output[count] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0)
{
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + 1 + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + 1 + nTabs + b] = ' ';
return pos + nTabs + nSpaces + 1;
}
else if (x == 0)
{
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + nTabs + b] = ' ';
return pos + nTabs + nSpaces;
}
}
Because the whitespace sequences of 8 characters are replaced by a single character (the tab), the number of read bytes from the input do not match to the written bytes in the output. A simple solution for this, is to simply keep track of two variables, one for the read bytes from the input, and one for the written bytes to the output. You could do this somewhat neater with pointers, though if you are following the book in a linear fashion, IIRC pointers are introduced later on.
Untested (namely for demonstrative purposes) code below.
NOTE: I took some liberties in reformatting your code for brevity.
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0) {
int space = 0;
int pos = 0;
int read_bytes = 0;
int write_bytes = 0;
while(read_bytes < i) {
if (line[read_bytes] != ' ') {
space = 0;
output[write_bytes++] = line[read_bytes];
}
else if (line[read_bytes] == ' ') {
space++;
if (line[read_bytes + 1] != ' ') {
if (space > TAB) {
write_bytes += entab(output, write_bytes, space);
} else {
for (int i = 0; i < space; i++)
output[write_bytes++] = ' ';
}
}
}
read_bytes++;
}
if (line[read_bytes] == '\n') {
output[write_bytes++] = line[read_bytes];
}
output[write_bytes] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0) {
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + 1 + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + 1 + nTabs + i] = ' ';
return nTabs + nSpaces + 1;
} else if (x == 0) {
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + nTabs + i] = ' ';
}
return nTabs + nSpaces;
}
In my solution I used external variables for index counter of output line.
And I made separated function for converting input array to output array.
#include <stdio.h>
#define TAB 8
#define MAX 100;
int j; //counter of newline
char line[MAX];
char newline[MAX];
int getter(void);
void converter(void);
int entab(int space_counter, int line_index);
int main()
{
extern char line[];
extern char newline[];
int len;
while ((len = getter()) > 0) {
converter();
printf("%s", newline);
}
}
int getter()
{
int c;
int i;
i = 0;
while ((c = getchar()) != EOF && c != '\n' && i < 30-1) {
line[i] = c;
++i;
}
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void converter(void)
{
extern int j;
extern char line[];
extern char newline[];
int space_counter;
int i;
i = j = 0;
space_counter = 0;
while (line[i] != '\0') {
while (line[i] == ' ') {
space_counter++;
i++;
}
if (space_counter > 0) {
j = entab(space_counter, i);
space_counter = 0;
}
else {
newline[j] = line[i];
j++;
i++;
}
}
newline[j] = '\0';
}
int entab(int space_counter, int end_point)
{
extern int j;
extern char newline[];
int new_index;
int start_point;
int tab_qty;
int space_qty;
start_point = end_point - space_counter;
tab_qty = end_point / TAB - start_point / TAB;
if (TAB > start_point)
space_qty = space_counter;
else
space_qty = end_point % TAB;
for (tab_qty; tab_qty > 0; tab_qty--) {
newline[j] = '\t';
j++;
}
for (space_qty; space_qty > 0; space_qty--) {
newline[j] = '|';
j++;
}
return new_index = j;
}
I have a program which solves maze, so that it finds possible route from Start(S) to Exit(E).Here is my Maze:
1111S11110
0000010001
110100010d
t001111110
0100000001
0111111101
1111111101
00000D01T1
0111110001
0000E01110
The possible route to it is :
Start S W W S S S E E E E E E S S S S W W N W W W W W W S S E E E E Exit
which is correct and i get it on CodeBlocks, However when i compile my code on dev through putty i get this:
Start S S S S S W N N W S W N N N W N Exit
Here is my whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Global Variables for use
int matrixSize,startX,startY,exitX,exitY;
char src[1500] = " ";
char Ndirection[50] = " N ";
char Sdirection[50] = " S ";
char Edirection[50] = " E ";
char Wdirection[50] = " W ";
// Function for finding the array length
int numOfLines(FILE *const mazeFile) {
int c, count;
count = 0;
for (;; ) {
c = fgetc(mazeFile);
if (c == EOF)
break;
if (c == '\n')
++count; // end of line => increment line counter
}
rewind(mazeFile);
return count+1;
}
int capLetter(char ch){
int result = 0;
if(ch >= 'A' && ch <= 'Z'){
result = 1;
}
return result;
}
int lowLetter(char ch){
int result = 0;
if(ch >= 'a' && ch <= 'z'){
result = 1;
}
return result;
}
int isSafe(char Mazearray[matrixSize][matrixSize],int x,int y){
if(x >= 0 && x < matrixSize && y >= 0 && y < matrixSize && Mazearray[x][y] != '1'){
return 1;
}
return 0;
}
void MazeSolution(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(recursiveMaze(Mazearray,x,y,pathArray,wasHereArray) == 0){
printf("There does not exist a possible solution!!!");
}
else{
pathArray[startX][startY] = 'S';
}
}
int recursiveMaze(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(x == startX && y == startY){
pathArray[x][y] = 'S';
}
if(x == exitX && y == exitY){
pathArray[x][y] = 'E';
return 1;
}
// check if the coordinate is safe to go(not 1)
if(isSafe(Mazearray,x,y) == 1 && wasHereArray[x][y] != '1'){
wasHereArray[x][y] = '1';
// Move North
if(recursiveMaze(Mazearray,x-1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Ndirection);
return 1;
}
// Move South
if(recursiveMaze(Mazearray,x+1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Sdirection);
return 1;
}
// Move East
if(recursiveMaze(Mazearray,x,y+1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Edirection);
return 1;
}
// Move West
if(recursiveMaze(Mazearray,x,y-1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Wdirection);
return 1;
}
}
return 0;
}
// Main Function
int main( int argc, char **argv )
{
// Opening the Matrix File
FILE *mazeFile;
mazeFile = fopen(argv[1], "r" );
if( mazeFile == NULL )
return 1;
matrixSize = numOfLines( mazeFile );
// Reading text file into 2D array
int i,j;
char mazeArray [matrixSize][matrixSize];
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
fscanf(mazeFile, "%c", &mazeArray[i][j]);
}
char eol;
fscanf(mazeFile, "%c", &eol);
}
// Variables
//Creating path array
char pathArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
pathArray[i][j] = '0';
}
}
// CheckPoint array
char wasHereArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
wasHereArray[i][j] = '0';
}
}
// Finding start and exit indexes
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
if(mazeArray[i][j] == 'S'){
startX = i;
startY = j;
}
if(mazeArray[i][j] == 'E'){
exitX = i;
exitY = j;
}
}
}
MazeSolution(mazeArray,startX,startY,pathArray,wasHereArray);
char *data = src;
int length=strlen(data);
char bytes[length];
int n=0;
while(n<=length)
{
bytes[n] = data[length-n-1];
n++;
}
FILE *f = fopen("path.txt", "w");
fprintf(f, "Start %s Exit",bytes);
fclose(mazeFile);
fclose(f);
return 0;
}
I don't know what is wrong and where to start?
DOS line endings are CR-LF ("\r\n") and *nix line endings are just LF ("\n"). Change these lines main:
char eol;
fscanf(mazeFile, "%c", &eol);
to:
int c = fgetc(mazefile); // Slurp a '\r' carriage return or '\n' linefeed character.
if ('\r' == c) {
c = fgetc(mazefile); // slurp the '\n' linefeed character.
}
I want to write below code with proper if clause.
int main()
{
float a,b;
printf("Enter Two number with space:\n");
scanf("%f %f",&a,&b);
//if(%a || b are char%)
printf("Not correct format!")
else
printf("a and b: %.2f %.2f",a,b);
return 0;
}
#define INT_CONVERTED (1 << 0)
#define FLOAT_CONVERTED (1 << 1)
int ReadNumber(const char *str, double *db, int *in)
{
int result = (str == NULL || db == NULL || in == NULL) * -1;
int len = 0;
char *tmp;
if (result != -1)
{
tmp = (char *)malloc(strlen(str) + 1);
strcpy(tmp, str);
for (int i = strlen(str) - 1; i >= 0; i--)
{
if (isspace(tmp[i]))
{
tmp[i] = 0;
continue;
}
break;
}
if (strlen(tmp))
{
if (sscanf(tmp, "%lf%n", db, &len) == 1 && strlen(tmp) == len)
{
result |= FLOAT_CONVERTED;
}
if (sscanf(tmp, "%d%n", in, &len) == 1 && strlen(tmp) == len)
{
result |= INT_CONVERTED;
}
}
free(tmp);
}
return result;
}
My file input contains the chars "abc" and is supposed to generate the hash: "a9993e364706816aba3e25717850c26c9cd0d89d" Instead, my output is 2474716729 148412417 414899454 2419217526 3285377520. My bit shifting should be correct but when I print out my W[t] I'm pretty sure the numbers are wrong.
#include <stdio.h>
#define MAX_SIZE 1048576
static unsigned char buffer[MAX_SIZE];
static unsigned int message[MAX_SIZE];
unsigned int readFile(unsigned char buffer[])
{
size_t length = 0;
int b = 0;
for (b = 0; b < MAX_SIZE; b++)
{
buffer[b]= '\0';
}
int i = 0;
char *fileName = "abc.txt";
FILE *filePointer = fopen(fileName, "r");
if (filePointer != NULL)
{
length = fread(buffer, sizeof(char), MAX_SIZE, filePointer);
if (ferror(filePointer)!= 0)
{
fputs("Error", stderr);
}
if (length > MAX_SIZE)
{
fputs("Input file too big for program", stderr);
}
//add one bit;
buffer[length] = 0x80;
//length++;
}
/*for (i = 0; i < MAX_SIZE; i++)
{
printf("%c", buffer[i]);
}
*/
fclose(filePointer);
return length;
}
unsigned int calculateBlocks(unsigned int sizeOfFileInBytes)
{
int blockCount = (((8 * sizeOfFileInBytes) + 1) / 512) + 1;
if((((8 * sizeOfFileInBytes) + 1) % 512) > (512 - 64))
{
blockCount = blockCount + 1;
}
//printf("here's block count: %i", blockCount);
return blockCount;
}
void convertCharArrayToIntArray(unsigned char buffer[], unsigned int
message[], unsigned int sizeOfFileInBytes)
{
int e = 0;
int d = 0;
//buffLength shows me how many chars are in array
size_t buffLength= strlen((char*)buffer);
//printf("this is bufflength: %zu -done", buffLength);
buffLength = buffLength/4;
for (e=0 ; e< buffLength; e++)
{
message[e] |= (buffer[e] <<24);
message[e] |= (buffer[e+1] <<16);
message[e] |= (buffer[e+2] <<8);
message[e] |= (buffer[e+3]);
}
/*for (d = 0; d <MAX_SIZE; d++)
{
printf("%i", message[d]);
} */
//printf("- done with message[d]");
}
void addBitCountToLastBlock(unsigned int message[], unsigned int
sizeOfFileInBytes, unsigned int blockCount)
{
int indexOfEndOfLastBlock = blockCount* 16 -1;
//printf("the size of file in bytes is: %i -done",
sizeOfFileInBytes);
sizeOfFileInBytes = sizeOfFileInBytes * 8;
message[indexOfEndOfLastBlock] = sizeOfFileInBytes;
//printf("index of last block is %i", message[indexOfEndOfLastBlock]);
int d = 0;
/* for (d = 0; d <MAX_SIZE; d++)
{
printf("%i", message[d]);
}
printf("- done with message[d]"); */
}
unsigned int K(unsigned int t)
{
unsigned int kHex[] = {0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
if (t>= 0 && t <= 19)
{
return kHex[0];
}
else if (t>= 20 && t <= 39)
{
return kHex[1];
}
else if (t>= 40 && t <= 59)
{
return kHex[2];
}
else if (t>= 60 && t <= 79)
{
return kHex[3];
}
return 0;
}
unsigned int f(unsigned int t, unsigned int B, unsigned int C, unsigned
int D)
{
if (t>= 0 && t <= 19)
{
return (B & C) |((~B)&D);
}
else if (t>= 20 && t <= 39)
{
return B^C^D;
}
else if (t>= 40 && t <= 59)
{
return (B & C) | (B & D) | (C & D);
}
else if (t>= 60 && t <= 79)
{
return B^C^D;
}
return 0 ;
}
void computeMessageDigest(unsigned int message[], unsigned int
blockCount)
void computeMessageDigest(unsigned int message[], unsigned int
blockCount)
{
unsigned int A, B, C, D, E;
unsigned int h[5];
unsigned int W[80];
unsigned int t = 0;
unsigned int temp; //temporary word value
unsigned int bCounter = 0;
int i = 0;
int d = 0 ;
// int z = 0;
//int blCount = 0;
/* for (d = 0; d <MAX_SIZE; d++)
{
printf("%i", message[d]);
}
printf("- done with message[d]"); */
int wInc = 0;
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
h[3] = 0x10325476;
h[4] = 0xc3d2e1f0;
while ( bCounter < blockCount)
{
for (i= 16 * bCounter; i < 16 *bCounter +16; i++)
{
W[wInc] = message[i];
wInc++; //block one
}
wInc = 0;
/*for (z = 0; z < 16; z++)
{
printf("%i", W[z]);
} */
for (t = 16; t < 80; t++)
{
W[t] = (W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]) << 1;
// printf("%u ", W[t]);
}
A = h[0];
B = h[1];
C = h[2];
D = h[3];
E = h[4];
for (t = 0; t < 80; t++)
{
temp = (A << 5) + f(t, B, C, D) + E + W[t] + K(t);
E = D;
D = C;
C = B << 30;
B = A;
A = temp;
}
printf("Hex values for A, B, C, D, E");
printf("%u, %u, %u, %u, %u", A, B, C, D, E) ;
h[0] += A;
h[1] += B;
h[2] += C;
h[3] += D;
h[4] += E;
int b = 0;
for (b = 0; b <5; b++)
printf("%u ", h[b]);
bCounter++;
}
int main(int argc, const char * argv[]) {
// insert code here...
unsigned int blockCount = 0;
unsigned int sizeOfFile = 0;
sizeOfFile = readFile(buffer);
/*for (i = 0; i < MAX_SIZE; i++)
{
printf("%c", buffer[i]);
} */
//printf("%i is the size", readFile(buffer));
blockCount = calculateBlocks(sizeOfFile);
convertCharArrayToIntArray(buffer, message, sizeOfFile);
//printf("\n");
addBitCountToLastBlock(message, sizeOfFile, blockCount);
computeMessageDigest(message, blockCount);
return 0;
I had used this code from https://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c
This code was for file compression. I had modified it for a given string. For example :
d(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):WritingModule:SecurityConfigD/6LoWPANd(2306):WritingModule:RunCoordinatorD/6LoWPANd(2306):RequestingmoduleaddressD/6LoWPANd(2306):WritingModule:GetAddressD/smartcard-jni(2781):SmartCard_state_update_callback:status=6D/SmartCardNative(2781):status=6D/smartcard(2781):PN532Smartcard_loop_threadexitD/smartcard-jni(2781):SmartCard_loop_thread:SMARTCARD_STATUS_ABORTD/smartcard(2781):Smartcard_loop_uninitD/smartcard(2781):2D/serialcomm_pn532(2781):PN532:Readingfrom/dev/ttyUSB0-->D/smartcard(2781):Received(0x3)fromPN532:(dataBuf[0]:0x1)(0x1f5988)D/smartcard(2781):ReceivedStatusfromPN532:OK(cmd:0x2)D/smartcard-jni(2781):SmartCard_listener_update_callbackD/smartcard(2781):Received(0x1c2)fromPN532:(dataBuf[0]:0x32)(0x1f5988)D/smartcard(2781):vd(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):
The problem I am facing is, if I want to compress a file containing this , the code is able to do that. But the modified code that I had done having little bit of problem. The last 2 bits of compressed files are different. Though the content of file and the buffer both are exactly same.
The original code was reading from file. Here, I provided the string of same content.
The code goes here :
/* LZSS encoder-decoder (c) Haruhiko Okumura */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EI 11 /* typically 10..13 */
#define EJ 4 /* typically 4..5 */
#define P 1 /* If match length <= P then output one character */
#define N (1 << EI) /* buffer size */
#define F ((1 << EJ) + P) /* lookahead buffer size */
int bit_buffer = 0, bit_mask = 128;
unsigned long codecount = 0, textcount = 0;
unsigned char buffer[N * 2];
FILE *infile, *outfile, *outfile2, *outfile3;
/*----*/
unsigned long payload_i = 0;
int tt = 0;
unsigned int buf_load[16000];
unsigned char *string_buf= "d(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):WritingModule:SecurityConfigD/6LoWPANd(2306):WritingModule:RunCoordinatorD/6LoWPANd(2306):RequestingmoduleaddressD/6LoWPANd(2306):WritingModule:GetAddressD/smartcard-jni(2781):SmartCard_state_update_callback:status=6D/SmartCardNative(2781):status=6D/smartcard(2781):PN532Smartcard_loop_threadexitD/smartcard-jni(2781):SmartCard_loop_thread:SMARTCARD_STATUS_ABORTD/smartcard(2781):Smartcard_loop_uninitD/smartcard(2781):2D/serialcomm_pn532(2781):PN532:Readingfrom/dev/ttyUSB0-->D/smartcard(2781):Received(0x3)fromPN532:(dataBuf[0]:0x1)(0x1f5988)D/smartcard(2781):ReceivedStatusfromPN532:OK(cmd:0x2)D/smartcard-jni(2781):SmartCard_listener_update_callbackD/smartcard(2781):Received(0x1c2)fromPN532:(dataBuf[0]:0x32)(0x1f5988)D/smartcard(2781):vd(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):";
/*----*/
void error(void)
{
printf("Output error\n"); exit(1);
}
void putbit1(void)
{
outfile2 = fopen("file2.lzss", "a");
bit_buffer |= bit_mask;
if ((bit_mask >>= 1) == 0) {
/*----*/
buf_load[payload_i] = bit_buffer;
if (fputc(buf_load[payload_i], outfile3) == EOF) error();
payload_i++;
/*----*/
if (fputc(bit_buffer, outfile2) == EOF) error();
if (fputc(bit_buffer, outfile) == EOF) error();
bit_buffer = 0; bit_mask = 128; codecount++;
}
fclose(outfile2);
}
void putbit0(void)
{
outfile2 = fopen("file2.lzss", "a");
if ((bit_mask >>= 1) == 0) {
/*----*/
buf_load[payload_i] = bit_buffer;
if (fputc(buf_load[payload_i], outfile3) == EOF) error();
payload_i++;
/*----*/
if (fputc(bit_buffer, outfile2) == EOF) error();
if (fputc(bit_buffer, outfile) == EOF) error();
bit_buffer = 0; bit_mask = 128; codecount++;
}
fclose(outfile2);
}
void flush_bit_buffer(void)
{
outfile2 = fopen("file2.lzss", "a");
if (bit_mask != 128) {
if (fputc(buf_load[payload_i], outfile3) == EOF) error();
if (fputc(bit_buffer, outfile2) == EOF) error();
if (fputc(bit_buffer, outfile) == EOF) error();
codecount++;
}
fclose(outfile2);
}
void output1(int c)
{
int mask;
putbit1();
mask = 256;
while (mask >>= 1) {
if (c & mask) putbit1();
else putbit0();
}
}
void output2(int x, int y)
{
int mask;
putbit0();
mask = N;
while (mask >>= 1) {
if (x & mask) putbit1();
else putbit0();
}
mask = (1 << EJ);
while (mask >>= 1) {
if (y & mask) putbit1();
else putbit0();
}
}
void encode(void)
{
int i, j, f1, x, y, r, s, bufferend, c;
for (i = 0; i < N - F; i++) buffer[i] = ' ';
for (i = N - F; i < N * 2; i++) {
if ((c = fgetc(infile)) == EOF) break;
if((c = string_buf[tt++]) == '\0') break;
buffer[i] = c; textcount++; //tt++;
}
bufferend = i; r = N - F; s = 0;
while (r < bufferend) {
f1 = (F <= bufferend - r) ? F : bufferend - r;
x = 0; y = 1; c = buffer[r];
for (i = r - 1; i >= s; i--)
if (buffer[i] == c) {
for (j = 1; j < f1; j++)
if (buffer[i + j] != buffer[r + j]) break;
if (j > y) {
x = i; y = j;
}
}
if (y <= P) output1(c);
else output2(x & (N - 1), y - 2);
r += y; s += y;
if (r >= N * 2 - F) {
for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
bufferend -= N; r -= N; s -= N;
while (bufferend < N * 2) {
if ((c = fgetc(infile)) == EOF) break;
if((c = string_buf[tt++]) == '\0') break;
//tt++;
buffer[bufferend++] = c; textcount++;
}
}
}
flush_bit_buffer();
printf("text: %ld bytes\n", textcount);
printf("code: %ld bytes (%ld%%)\n",
codecount, (codecount * 100) / textcount);
}
int getbit(int n) /* get n bits */
{
int i, x;
static int buf, mask = 0;
x = 0;
for (i = 0; i < n; i++) {
if (mask == 0) {
if ((buf = fgetc(infile)) == EOF) return EOF;
mask = 128;
}
x <<= 1;
if (buf & mask) x++;
mask >>= 1;
}
return x;
}
void decode(void)
{
int i, j, k, r, c;
for (i = 0; i < N - F; i++) buffer[i] = ' ';
r = N - F;
while ((c = getbit(1)) != EOF) {
if (c) {
if ((c = getbit(8)) == EOF) break;
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
} else {
if ((i = getbit(EI)) == EOF) break;
if ((j = getbit(EJ)) == EOF) break;
for (k = 0; k <= j + 1; k++) {
c = buffer[(i + k) & (N - 1)];
fputc(c, outfile);
buffer[r++] = c; r &= (N - 1);
}
}
}
}
int main(int argc, char *argv[])
{
int enc;
char *s;
memset(buf_load, '\0', sizeof(buf_load));
outfile3 = fopen ("file1.lzss", "wb");
if (argc != 4) {
printf("Usage: lzss e/d infile outfile\n\te = encode\td = decode\n");
return 1;
}
s = argv[1];
if (s[1] == 0 && (*s == 'd' || *s == 'D' || *s == 'e' || *s == 'E'))
enc = (*s == 'e' || *s == 'E');
else {
printf("? %s\n", s); return 1;
}
if ((infile = fopen(argv[2], "rb")) == NULL) {
printf("? %s\n", argv[2]); return 1;
}
if ((outfile = fopen(argv[3], "wb")) == NULL) {
printf("? %s\n", argv[3]); return 1;
}
if (enc) encode(); else decode();
fclose(infile); fclose(outfile);
fclose(outfile3);
return 0;
}
Looks like the issue lies in buffer reading-writing vs file read write. In file read-write the pointer is increased to next mem loc and reading and writing the same way. In string, each array is being read by incrementing index and then the compressed value is written in file in file write. In file, it is read as binary (wb), In string it is being read as array element. Can there be a problem for that ? Need expert's advice on that.
void flush_bit_buffer(void)
{
outfile2 = fopen("file2.lzss", "a");
if (bit_mask != 128) {
flush_bit[payload_i] = bit_buffer; /*This last bit should be put which I missed. It solved my issue*/
if (fputc(buf_load[payload_i], outfile3) == EOF) error();
if (fputc(bit_buffer, outfile2) == EOF) error();
if (fputc(bit_buffer, outfile) == EOF) error();
codecount++;
}
fclose(outfile2);
}
I solved it by adding the line in the code snippet. I needed to add last bit of bit buffer which solved the problem.