How to XOR two byte streams in C? - c

I've been reading through SO for the past couple of days trying to figure this out, I am stumped. I want to read in two 32 bit byte arrays (from stdin, input will be hex) and xor them, then print the result.
So far I've tried using scanf, fgets, and gets. My thought was to read the large hex numbers into a char buffer and perform the xor in a for loop until I hit an EOL (with fgets) or a null terminator. So far my output is not even close. I tried lots of variations, but I will only post my latest fail below. The challenge I've been trying to complete is: http://cryptopals.com/sets/1/challenges/2/
I am trying it in C because I'm really trying to learn C, but I'm really getting frustrated with none of these attempts working.
#include <stdio.h>
#include <math.h>
int main()
{
char buff1[100];
char buff2[100];
char buff3[100];
int size = sizeof(buff1);
puts("Enter value\n");
fgets(buff1, size, stdin);
puts(buff1);
puts("Enter value\n");
fgets(buff2, size, stdin);
puts(buff2);
for (int i = 0; i != '\n'; i++) {
buff3[i] = buff2[i] ^ buff1[i];
printf("%x", buff3[i]);
}
return 0;
}

When using sizeof() it should be used with types, not data. For instance if you want space for 100 chars, you need to find the sizeof(char) and then multiply by 100 to find out how many bytes you need and that goes into the buffer. A char is usually a byte so expect 100 bytes. fgets() will work but I prefer to use this
int getchar()
Just stop when the the user
enters a newline/terminator character. Since you don't know how many characters will come in from stdin, you
need to dynamically increase the size of your buffer or it will overflow. For the purposes of this question you can just make it a very big array, check to see if its about to overflow and then terminate the program. So to recap the steps.
1.) Create a big array
2.) While loop over getchar() and stop when the output is the terminator, take note of
how many chars you read.
3.) Since both buffers are guaranteed to have equal chars make your
final array equal to that many chars in size.
4.) For loop over getchar() and as the chars come out, xor them with the first array
and put the result into the final array. You should try doing this with 1 array
afterwards to get some more C practice.
Good luck!
EDIT:
fgets() can be used but depending on the implementation it is useful to know how many chars have been read in.

#include <string.h>
#include <ctype.h>
static inline unsigned char hc2uc(char d){
const char *table = "0123456789abcdef";
return strchr(table, tolower(d)) - table;
}
...
for(int i=0;buff1[i]!='\n';i++){
buff3[i]=hc2uc(buff2[i])^hc2uc(buff1[i]);
printf("%x",buff3[i]);
}

Related

Using getchar() to read from file

I have an assignment and basically i want to read all the bytes from an audio file using getchar() like this:
while(ch = getchar()) != EOF)
At some point I have to read 4 consecutive bytes that stand for size of file and I can't understand the following:
If the file my program is reading is for example 150 bytes in size, that is enough to be stored in 1 of the 4 bytes, which means that 3 of the bytes will be 0 and the last one will be 150 in that case. I understand that I need to read all 4 bytes, through 4 repetitions of the while in the above section of cod, in order to get all the information I need, but what exactly is getchar() going to return to my variable, as it returns the ASCII code for the character it just read?
Also what happens for larger numbers, that can't be stored in a single byte?
Cant comment since i dont have enough reputation, i am deeply perplexed with your question for I do not understand what do you mean or what are you trying to achieve
The function getChar() should be used for returning mostly a single byte at a time, in fact only upon reading your question did i check the manual to learn it reads more than one although from my experience and the tests i performed now it seems it is used for reading multi byte characters heres the simple code i used to check for it
char * c;
printf("Enter character: ");
c = getchar();
printf("%s",c);
The character i used and this will probably unformat is the stack overflow glyph i use in my polybar, 溜, here it shows as an asian character.
Not only that but fgets will return EOF when arriving at the end of the file(or when an error occurs) as stated in the linux manual
https://linux.die.net/man/3/getchar
Also upon further reading it depends on how the file stores data, if its big endian the first byte read will be 0,0,0,150 else if its little endian it will be 150,0,0,0 but thats assuming it is reading 1 character at the time and not 4 at once as you described it
As for the "solution" of your question why not use fread() reading the 4 bytes at once or a derivative when it does it job properly?
EDIT
As asked by the comment the following "concatenates" the values bit-wise i used scanf because i was too lazy to manually check for every ASCII key, this assuming the file is big endian, ie 0,0,0,150 else invert the order in which the << is done and it should "just werk™"
#include <stdio.h>
#include <stdlib.h>
unsigned char c[4];
unsigned int dosomething(){
unsigned int result=0;
result= (unsigned int)c[0]<< 24 | (unsigned int)c[1]<< 16 | (unsigned int)c[2]<< 8 | (unsigned int)c[3];
return result;
}
int main(int argc, char const *argv[]){
for (size_t i = 0; i < 4; i++)
{
printf("Enter character: ");
scanf ("%u", &c[i]);
printf("%u\n", c[i]);
//printf("%s",c);
}
printf("%u",dosomething());
return 0;
}
Now for the fread it is used like the following fread(pointertodatatoread, sizeofdata, sizeofarray, filepointer);
for indepth look here is the manual:
https://www.tutorialspoint.com/c_standard_library/c_function_fread.htm
this should be asked in a different thread as i feel im asking another question
If the file my program is reading is for example 150 bytes in size, that is enough to be stored in 1 of the 4 bytes, which means that 3 of the bytes will be 0 and the last one will be 150 in that case. I understand that I need to read all 4 bytes in order to get all the information I need, but what exactly is getchar() going to return to my variable, as it returns the ASCII code for the character it just read?
getchar doesn't know anything about ASCII. It returns the numeric value of the byte it reads, or a special code, represented by EOF, if it cannot read a byte. If you treat the byte as an ASCII code then that's a matter of interpretation.
Thus, if your file size is encoded as as three zero bytes followed by one byte with value 150, then getchar() will return that as 0, 0, 0, and 150 on four consecutive calls.

Character Array and Null character

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
char str[4];
scanf("%s",str);
printf("%s",str);
}
input scan
output scan
Here I declare an array of 4 characters. I used '%s' that is used for strings. I am not able to understand how can we input 4 char elements and get correct answer when one space should be utilized for the NULL character. The input should only work with up to 3 elements.
scanf() does not check its arguments. You could even enter more than 4 characters and scanf() would happily overwrite the memory area that comes after your array. After that, your program might crash or all kinds of funny things might happen. This is called a buffer overflow and it is a common cause of vulnerabilities in software.
as mentioned when you take more than 3 character as input ,and extra chars and \0 will be written outside of array memory(after it) and over write memory which doesn't belong to array.which will cause undefined behavior.
but you can use these to prevent buffer overflow from happening:
scanf("%3s",str);
or
fgets(str, sizeof str, stdin)

How to declare a char array of size same as the size of the string entered at the runtime in C?

I want to get a string from the user, in a char array that have no fixed length. The length should be equal to the, length of the string that the user enters. I tried malloc(), but that also requires the size to be specified. Please help.
Please mark it, I want to use a char array, not a string type.
C strings do not pack their length with them. Every C string is a plain array of characters, with a null after the last char to indicate its end. Standard functions from the C IO library will generally receive, therefore, an array of chars and write data into it. The array will have to be big enough to hold everything that is typed by the user. Most functions won't even check for buffer overflows.
Now what you can do is ask first for the max length of the string the user is going to type and allocate exact memory, or you can declare a huge array and define its size as the max string length.
char bigBuffer[2048];
fgets(bigBuffer, 2048, stdin);
fgets() allows you to specify the maximum number of chars you are taking in. If the user types more than 2048 chars, in this example, fgets() it will return with an error and prevent your program from crashing.
It is not possible to allocate a memory with infinite length. Every memory is bound by size one way or other.
There are two ways to handle your situation.
1. Allocate a large memory which will not overrun any possible user input.
2. [Better Option] Use reasonable size memory and use function with length check like, fgets, to get user input.
What you need is a basic unlimited input function. The idea is to allocate a reasonably sized buffer for input, begin reading one char at a time, and if you exceed the buffer size to realloc it and increase its size.
You could optimize this a bit by reading strings the length of the remaining space, but that gets complicated and fiddly. Mainly not worth it.
I wrote this code off the top of my head so it probably won't compile and work as-is, but it should give you the basic idea.
char *buffer = malloc(100);
size_t bufferLen = 100;
size_t currLen = 0;
int c;
while ((c = getchar()) != EOF && c != '\n')
{
if (currLen > bufferLen-1) // -1 because must leave room for null terminator
{
bufferLen += 100;
buffer = realloc(buffer, bufferLen);
buffer[currLen++] = c;
}
else
buffer[currLen++] = c;
}
buffer[currLen] = '\0';
This can be done in indirect way.
Read one character at a time from input. Using malloc/realloc allocate memory in increasing fashion. It is not of constant order time and constant order memory algo but your functionality can be achieved.
Here is the code snippet for that.
char ch;
int count=0;
char *charArray=NULL;
printf("Enter string\n");
while((ch=getchar())!='\n')//This condition can be changed according to needs
{
count=count+1;
charArray=(char *)realloc(charArray,count);
charArray[count-1]=ch;
}
You create the array after the user has entered the string. Can't remember exact C syntax but something along the lines of
string word = "";
scanf("%s", word");
char myArray[word.length];

Can't find where is the segmentation fault in C program

#include<stdio.h>
#include<string.h>
int main()
{
char a[1000000];
int i,j;
int arr[1000000];
gets(a);
unsigned long int len=strlen(a);
if(len<1000000){
for(i=0,j=len-1;i<len&&j>=0;i++,j--)
arr[j]=a[i]-'0';
}
return 0;
}
I am using this code to store the number entered through keyboard into an integer array.But it keeps giving me segmentation fault.I don't know where it is.Plus I've heard gets() isn't a good option,
But I don't know how to use the alternative way to do it. It seems to be a fairly simple code.
Can anyone point where memory is leaking and why?
I have used the debugger on Code::Blocks,the call stack is empty.
The alternative to gets it's fgets:
fgets(a, sizeof(a), stdin);
You have placed two very large arrays on the stack. It's unlikely that your process was launched with a large enough stack (over 5MB). The arrays a and arr should be dynamically allocated using malloc() or calloc() and freed later using free().
Define your array a as follows:
char a[ 1000000 ] = { 0 };
The convention in C for strings is to have a NULL terminator. This ensures two things:
a does not take on values from a previous stack frame.
a has a NULL terminator at the end.
Remark:
Having an array of length 1 million will exhaust your call stack quite quickly.
Consider using a dynamic array to be more space efficient. You would need to read one byte at a time from stdin until EOF or new line is sent, implemented as follows:
for ( int byte = getchar(); byte != EOF && byte != '\n'; byte = getchar() ) {
dynarray_Add( dynArray, byte );
}
... where dynArray_Add would be some function that adds a character to your array of characters and performs the appropriately doubling when the length has reached the capacity.
If you are unfamiliar with a dynamic array, read more here.
There are a number of issues with your code. The most obvious is that you're allocating a huge amount of memory on the stack, which is a bad idea even if it isn't causing a problem in itself. You're also using an old, unsafe function (gets) and you're not doing appropriate error checking.
fgets is almost a drop-in replacement for gets, and it has better safety. Simply call it with fgets( a, 1000000, stdin ), and it will never overrun the size of your buffer. Check the return value against NULL and you won't have uninitialised memory issues. Use malloc to get memory and you won't have stack size issues (don't forget to free!). Finally, don't use ints for your loop when the length is stored as an unsigned long! In this case the size of the buffer means it can't be an infinite loop but it's still bad style (also I think you want size_t not unsigned long - They just happen to be the same on your system).

K&R Exercise 1.16 - Limitation on line length

I'm learning C from K&R's "The C Programming Language" book. I'm doing the exercises specified in the book. I'm on exercise number 1.16, but I don't understand it.
Exercise 1.16:
Revise the main routine of the longest-line program so it will
correctly print the length of arbitrarily long input lines, and as
much as possible of the text.
My questions:
"...as much as possible of the text..." - is there some limitation on string length? Maybe in standard headers there's a variable with the max allowed value of string length?
"...the length of arbitrarily long input lines..." - but in the code MAXLINE is defined as 1000. It is limited size too. I see some solutions here, but in my opinion it is not solution decision, since on the former there is a restriction on length of a line (1000 characters).
Maybe I don't understood the task. My understanding is I must remove the 1000-character limitation.
It's a pretty early exercise in K&R, you're just supposed to do some minor changes to the code, not a total redesign of the code.
"...as much as possible of the text..."
is up to you to interpret. I'd do it by printing what's stored in the longest buffer. i.e. print out up to 1000 characters of the line. Again, it's an early exercise, with little introduction to dynamically allocated memory yet. And at the time K&R was written, storing away arbitrarily long text lines wasn't as feasible as it is today.
"...the length of arbitrarily long input lines..."
Is a hard requirement. You're supposed to find the correct length no matter how long it is (at least within the bounds of an int. )
One way to solve this problem is:
After the call to getline(), check if the last character read into the line buffer is a newline ('\n')
If it is, you read a complete line. The len variable is the correct length of the line(the return value of getline(), and no special consideration is needed compared to to original code.
If it is not , you did not read the entire line, and need to hunt for the end of this line. You add a while loop, calling getchar() until it returns a newline (or EOF), and count the number of characters you read in that loop. Just do len++ to count.
When the while loop is done, the new len is now the actual length of the line, but our buffer just has the first 999 characters of it.
As before, you store away (the copy() function call) the current line buffer (max 1000 chars) if this line is the longest so far.
When you're done, you print out the stored line as before (the longest buffer) and the max variable for the length.
Due to the above mentioned while loop that max length is now correct.
If the longest line indeed was longer than 1000 chars. you at least print out those first 999 chars - which is "as much as possible".
I'll not spoil it and post the code you need to accomplish this, but it is just 6 lines of code that you need to add to the longest-line program of exercise 1-16.
On modern machines "as much as possible of the text" is likely to be all of the text, thanks to automatically line-wrapping terminal programs. That book was written when teletype terminals were still in use. There is no limitation on string length other than perhaps memory limitations of the machine you're working on.
They're expecting you to add some kind of loop to read characters and look for newlines rather than assuming that a read into the MAXLINE sized buffer is going to contain a newline for sure.
here is my version:
int getline(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;
}
if(c!=EOF)
{
while((c=getchar())!=EOF&&c!='\n')
i++;
}
s[i]='\0';
return i;
}
#define MAXLINE 1000
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max=0;
while((len=getline(line,MAXLINE))>1)
{
if(len>max)
{
max=len;
copy(longest,line);
}
}
if(max>0)
{
printf("%d:%s",max,longest);
}
return 0;
for some unknown reasons ,the example code doesn't work in my pc
particularly,when the condition is 'len>0',the loop won't end
i think the main reason is that when you type nothing,but you still have to press enter,so it is received as '\n',and the len is 1;
i think it satisfy the requirement that print the length of arbitrarily long input lines, and as much as possible of the text.
And it works like this
#include
main()
{
long tlength = 0;
short input, llength = 1;
while (llength > 0) {
llength = 0;
while ((input = getchar()) != EOF) {
++llength;
if (input == '\n')
break;
}
tlength = tlength + llength;
printf("\nLength of just above line : %5d\n\n", llength);
}
printf("\n\tLength of entire text : %8ld\n", tlength);
return 0;
}
According to me, This question only wants the length of each arbitrarily line + At last the length of entire text.
Try to run this code and tell me is it correct according to question because i too confuse in this problem.
I want to offer that this exercise actually makes more sense if imagine that the limit of the number of characters you can copy is very small -- say, 100 characters -- and that your program is supposed to judge between lines that are longer than that limit.
(If you actually change the limit so that it's very small, the code becomes easier to test: if it picks out the first line that hits that small limit, you'll know your code isn't working, whereas if it returns the first however-many characters of the longest line, it's working.)
Keep the part of the code that copies and counts characters until it hits a newline or EOF or the line-size-limit. Add code that picks up where this counting and copying leaves off, and which will keep counting even after the copying has stopped, so long as getchar() still hasn't returned an EOF or a newline.
My solution: just below the call to getLine
if ( line[len-1] != '\n' && line[len-1] != EOF) //if end of line or file wasnt found after max length
{
int c;
while ( ( c = getchar() ) != '\n' && c != EOF )
len++; //keep counting length until end of line or file is found
}
to test it, change MAXLINE to 25

Resources