decrypt/encrypt xor algorithm in C - c

Here, I'm trying to encrypt a message using XOR. However, when I run the program, I'm getting weird output (random outputs). I guess I'm missing something here.
my sample of code:
/*
* Description: Decipher the message using XOR and print it.
* Parameters:
* cipher: The cipher of the message (With the key embedded at the start)
* keyLength: The length of the key at the start of the message
*Return:
* None.
*Note:
Do not use any additional variables for this challenge.
*/
void print_cipher_message(unsigned char cipher[], int keyLength) {
// TODO: complete the function
//keyLength = 3;
for (int i = 0; i < strlen(cipher) && i <= keyLength; i++) {
i % keyLength;
cipher[i] = cipher[i] ^ keyLength;
// i% keyLength;// i % ;//cipher[i] % sizeof(keyLength);
printf("%c", cipher);
}
}
int main() {
unsigned char cipher[] = "\x12\x56\xd4\x61\x26\xbb\x7b\x3a\xbd\x7c\x31\xf4\x61\x3e\xbb\x65\x25\xf4\x7b\x25\xf4\x73\x76\x97\x40\x1f\x99\x57";
int keyLength = 3;
//print the cipher message
print_cipher_message(cipher, keyLength);
return 0;
}
The expecting result is as the following:
/*
EXAMPLE:
cipher="\x31\xf4\x61\x7a\x33\xb8\x7e\x39\xf4\x65\x39\xa6\x7e\x32\xf5\x33"
keyLength=3;
then the cipher is:
"\x31\xf4\x61\x7a\x33\xb8\x7e\x39\xf4\x65\x39\xa6\x7e\x32\xf5\x33"
^----Key-----^^-------------------Message------------------------^
*/
I Would appreciate your help. Thank you.

A couple of problems I see right away:
You're asking printf to print a char (%c) but are passing a pointer to char instead of a char.
There's a line i % keyLength that doesn't do anything, it just performs a calculation and discards the results.
Also you're calling strlen every time through the loop, which is going to be kind of expensive.
I think what you're expected to do here is have two indexes, one that loops over the range 0 to keyLength, and another that iterates over the string to encode (starting at index keyLength). The function ends when the second index reaches the end of the string.

At first, you need to understand question correctly. Your question states that key is embedded at start of your cipher and its length is keyLength. So you need to separate this part and xor it with the rest of cipher.
Code should be similar to this:
void print_cipher_message(unsigned char cipher[], int keyLength) {
for (int i = 0; i < strlen((char*)cipher) - keyLength; i++) {
cipher[i + keyLength] = cipher[i + keyLength] ^ cipher[i % keyLength];
}
printf("%s", cipher + keyLength);
}
I wrote it off top of head quickly without debugging, so it may have bugs. In addition, question is not correct itself. it needs length of cipher and we cannot really use strlen() for it.

Related

Why is the concatenated string at the end totally different from what the code does?

The code below might seem big, but it's really simple. I wanted to make an exercise generator in C, which concatenates latex formatted strings, stored in the function local arrays.
But the output is totally not what I expected it to be. I might have done something wrong with the pointers, or some overflow somewhere.
Tried all the tips I could find on internet:
(1) Initialize a string with '\0' at position 0;
(2) Use a pointer to the string to pass to the function;
int create_exercise_string(char **s, int s_size) {
// The format of the exercise is x+n=m;
// ASCII 48-57 = '0' ... '9';
int exercises_left = 10;
char *exercise;
char operation_list[][2] = {"+\0", "-\0"};
char equal[] = "&=&"; // & is for centering on the item contained in latex;
char array_begin[] = "\\begin{eqnarray*}\n";
char array_end[] = "\\end{eqnarray*}";
char number[1];
strcat(*s, array_begin);
s_size -= strlen(array_begin);
//REMOVE
puts("before exercise generation");
while (exercises_left > 0 && s_size > 0) {
exercise = malloc(256);
if (!exercise) {
puts("allocating error, quitting...");
getchar();
exit(1);
}
exercise[0] = '\0';
// THE INTERESTED PART =================================================
if (exercises_left < 10)
strcat(exercise, "\\\\\n");
printf("exercise number %d\n", exercises_left);
strcpy(exercise, "x");
//add an operator
strcat(exercise, operation_list[rand() % 2]);
// add a number
number[0] = (rand() % 10) + 48;
strcat(exercise, number);
// add an equal
strcat(exercise, equal);
// add a number
number[0] = (rand() % 10) + 48;
strcat(exercise, number);
// END =================================================================
s_size -= strlen(exercise);
strcat(*s, exercise);
free(exercise);
exercises_left--;
}
//REMOVE
puts("exercise generation ended");
if (s_size < strlen(array_end)) {
puts("create_exercise_string: buffer overflow detected, quitting...");
getchar();
exit(1); // for now... will be substituted with proper code
}
else strcat(*s, array_end);
puts("allocation worked, returning in main");
return exercises_left; // 0 if succesfull;
}
I was expecting the output to be like this
\begin{eqnarray*}
x-9&=&3\\
x+3&=&12\\
x-2&=&3\\
... 7 other exercises
\end{eqnarray*}
But I actually get
\begin{eqnarray*}
x-5\end{eqnarray*}&=&9\end{eqnarray*}x-9\end{eqnarray*}&=&2\end{eqnarray*}x+3\end{eqnarray*}&=&1\end{eqnarray*}x-7\end{eqnarray*}&=&0\end{eqnarray*}x+6\end{eqnarray*}&=&1\end{eqnarray*}x-6\end{eqnarray*}&=&5\end{eqnarray*}x+6\end{eqnarray*}&=&8\end{eqnarray*}x-8\end{eqnarray*}&=&6\end{eqnarray*}x+4\end{eqnarray*}&=&5\end{eqnarray*}x+1\end{eqnarray*}&=&5\end{eqnarray*}\end{eqnarray*}
With no \n added overall, and some \end{eqnarray*} repeatedly added...
What is wrong?
I managed to fix it.
All I can say is, when working with strings, always keep in mind if the terminating character is added or not, so in my case, I need to reinforce the study of strings allocation in C.
The problem was the variable number[1].
number[0] = rand() % 10 + 48;
This code adds the char representation of a number between 0 and 9 [48,57] in ASCII.
But it doesn't add a terminating null character!
Everytime I concatenated number to the exercise string, it overflowed to another local variable which had the terminating null character, thus the "undefined behaviour" of strcat() was that it kept reading another local variable.
Lucky me in memory there was a '\0' minefield, otherwise I would have needed to bang my head on the wall, if protected memory was tried to be read.
Thanks for the help!

Encrypt a message in C

I have to write a function to encrypt a message given as a string input using the given encryption key. The function should output the encrypted message as a string to encryptedMessage in the argument list. The function prototype must be as follows: void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey); The function must take the encryption key and convert each of its characters, which represent hexadecimal digits, to their equivalent decimal values as integers. I already wrote a function to convert hex2decimal. The message must then be encrypted by adding the first of these integer values to the ASCII value of the first character in the message, and the second of the integer values to the second character in the message, and so on, and start again with the first integer value after every 16. This will be necessary if the message is longer than the encryption key, which will usually be the case.
here is some of my code so far:
void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey)
{
int *arr = malloc(sizeof(int)*getStringLength(encryptionKey));
int i;
for(i = 0;i < getStringLength(encryptionKey);i++){
arr[i] = hexDigit2Dec(encryptionKey[i]);
message[i] = message[i] + (char)arr[i];
if(getStringLength(message ) > getStringLength(encryptionKey)){
i = 0;
}
}
free(arr);
}
when i run it "project.exe has stopped" pops up. Please help me out, i am new at C and struggling a lot.
You need 2 counters: one for the encryption key position and one for the character being worked on.
You are using one and resetting it to zero whenever the message gets longer than the key causing an infinite loop
for ( keyPos = 0, msgPos = 0; msgPos < getStringLength(message ); ++keyPos, ++msgPos )
{
// calculate and append next char to encrypted message here
if ( keyPos >= getStringLength(encryptionKey)
{
keyPos = 0;
}
}
You'll have to learn to do some planning first and think about what you need to do ... I'll try to give kind of a step by step coding here so hopefully you will see where you went wrong.
But first, there's a standard C function for getting the length of a string: strlen(). I will use this. If you have certain requirements to use something different instead, oh well.
Let's start with the prototype you were given:
void encryptMessage(char *encryptedMessage, char *message, char *encryptionKey)
{
It's a bit ambiguous, but I guess encryptedMessage should be the output. For a real-world project, make it explicit by adding a const to the other pointers. But for now, let's ignore that. As encryptedMessage is a parameter here and not the return value, I assume it's the callers responsibility to provide storage. So, move on ...
You will need the length of your encryptionKey multiple times, let's put it in a variable:
size_t keyLen = strlen(encryptionKey);
And then you need the integer values of the key hex digits multiple times, too, so let's pre-calculate them:
char *keyDigits = malloc(keyLen); // we only need char-sized integers here
for (int i = 0; i < keyLen; ++i)
{
keyDigits[i] = (char)hexDigit2Dec(encryptionKey[i]);
}
Now it's time for the main loop ... you just need to take each character of message and add a value from keyDigits to it:
int keyPos = 0;
for (int i = 0; i < strlen(message); ++i)
{
encryptedMessage[i] = message[i] + keyDigits[keyPos];
if (++keyPos == keyLen) keyPos = 0;
}
And that's it ... free your temporary array and you're done.
free(keyDigits);
}

Accounting for no existant characters as inputs C

Sorry if the question title is a little bit off, I had no idea what to call it just because it is such a peculiar question. What I am aiming to do is decode an input string encoded using a method I will explain in a bit, into a plain English text.
Encoding is done by choosing an integer nRows between 2 and half the length of the message, e.g. a message of length 11 would allow values of nRows in the range 2 to 5. The message is then written down the columns of a grid, one character in each grid cell, nRows in each column, until all message characters have been used. This may result in the last column being only partially filled. The message is then read out row-wise.
For example if the input message was ALL HAIL CAESAR, and the nRows value was 2, encoding would look like this:
A L H I A S R
L A L C E A #
Where # symbolizes a or blank character in the table, that doesn't actually exist - I have simply added it to explain the next part :)
The actual question I have is decoding these phrases. The code I have written thus far works for a few problems, but once the blank characters (#) become many the code begins to break down, as the code obviously does not register them and the algorithm skips past them.
My code is:
/*
* DeConfabulons.c
* A program to Decode for the Confabulons
*
* August 9th 2015
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
//A simple function confab which given input text encoded using
//the Confabulons encoding scheme, and a number of rows, returns
//the originally encoded phrase.
void deconfab(const char inText[], int nRows, char outText[])
{
int count = 0;
int i = 0;
int len = strlen(inText);
float help = ((float)len/(float)nRows);
int z = 0;
while (z < round(help))
{
while (((int)inText[count] > 0) && (count <= len))
{
outText[i] = inText[count];
i ++;
if (count < (int)help)
{
count = count + round((int)help+0.5);
}
else
{
float helper = count + help;
count = round(helper);
}
}
z ++;
count = z;
}
outText[i] = '\0';
}
Which thus far works for the Caesar example I gave earlier. The encoded form of it was ALHI ASRL ALCEA. The main(void) input I have been provided for that problem was:
char buffer[40] = {'\0'};
deconfab("ALHI ASRL ALCEA", 2, buffer);
printf("%s\n", buffer);
Which correctly outputs:
ALL HAIL CAESAR
However when working with cases with extra "blank" characters such as:
char buffer[60] = {0};
char* s = "Two hnvde eo frgqo .uxti hcjeku mlbparszo y";
deconfab(s, 13, buffer);
printf("%s\n", buffer);
The output should be:
The quick brown fox jumps over the lazy dog.
However my code will return:
Thdefq.the browneorouickmps ov g x julazy
I have concluded that this caused by the blank characters at the end in the last column by running through multiple tests by hand, however no matter what I try the code will not work for every test case. I am allowed to edit the bulk of the function in nearly any way, however any inputs or anything in int main(void) is not allowed to be edited.
I am simply looking for a way to have these blank characters recognized as characters without actually being there (as such) :)
First of all, as far as I see, you don't include those "null" characters in your input - if you did that (I guess) by adding any "dummy" characters, the algorithm would work. The reason it does in the first case is that the 'blank' character is missing at the end of the input - the same place as it's missing in the sentence.
You can try to make a workaround by guessing the length of a message with those dummy characters (I'm not sure how to formulate this) like:
ALHI ASRL ALCEA has 15 characters (15 mod 2 = 1) but ALHI ASRL ALCEA# has 16 characters. Similarly, Two hnvde eo frgqo .uxti hcjeku mlbparszo y has 44 characters (44 mod 13 = 5) so you need quite a lot of the dummy chars to make this work (13-5=8).
There are several ways at this point - you can for instance try to insert the missing blank spaces to align the columns, copy everything into a 2-dimensional array char by char, and then read it line by line, or just determine the (len mod rows) characters from the last column, remove them from the input (requires some fiddling with the classic C string functions so I won't give you the full answer here), read the rest and then append the characters from the last column.
I hope this helps.
There is some mess with index calculation.
At first it is pure discrete transformation. So, it should be implemented using only integer numbers.
The function below does what you need.
void deconfab(const char inText[], int nRows, char outText[])
{
int len = strlen(inText);
int cols = len / nRows;
int rows_with_large_cols = len % nRows;
int count = 0;
int col = 0;
int row = 0;
while (count < len)
{
int idx;
if (row < rows_with_large_cols)
idx = row * (cols + 1) + col;
else
idx = rows_with_large_cols * (cols + 1) +
(row - rows_with_large_cols) * cols + col;
if (idx > len - 1) {
++col;
row = 0;
idx = col;
}
outText[count] = inText[idx];
++row;
++count;
}
outText[count] = '\0';
}
It may be rewritten more nicely. Now it is like a pseudocode to explain the algorithm.
You cannot use the standard str* functions if you are going to handle nulls. You must, instead, work with the data directly and use the *read family of functions to get your data.

Boyer-Moore Algorithm

I'm trying to implement Boyer-Moore Algorithm in C for searching a particular word in .pcap file. I have referenced code from http://ideone.com/FhJok5. I'm using this code as it is.
Just I'm passing packet as string and the keyword I'm searching for to the function search() in it. When I'm running my code it is giving different values every time. Some times its giving correct value too. But most of times its not identifying some values.
I have obtained results from Naive Algo Implementation. Results are always perfect.
I am using Ubuntu 12.0.4 over VMware 10.0.1. lang: C
My question is It has to give the same result every time right? whether right or wrong. This output keeps on changing every time i run the file on same inputs; and during several runs, it gives correct answer too. Mostly the value is varying between 3 or 4 values.
For Debugging I did so far:
passed strings in stead of packet every time, Its working perfect and same and correct value every time.
checking pcap part, I can see all packets are being passed to the function (I checked by printing packet frame no).
same packets I am sending to Naive Algo code, its giving perfect code.
Please give me some idea, what can be the issue. I suspect some thing wrong with memory management. but how to find which one?
Thanks in advance.
# include <limits.h>
# include <string.h>
# include <stdio.h>
# define NO_OF_CHARS 256
// A utility function to get maximum of two integers
int max (int a, int b) { return (a > b)? a: b; }
// The preprocessing function for Boyer Moore's bad character heuristic
void badCharHeuristic( char *str, int size, int badchar[NO_OF_CHARS])
{
int i;
// Initialize all occurrences as -1
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
// Fill the actual value of last occurrence of a character
for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
/* A pattern searching function that uses Bad Character Heuristic of
Boyer Moore Algorithm */
void search( char *txt, char *pat)
{
int m = strlen(pat);
int n = strlen(txt);
int badchar[NO_OF_CHARS];
/* Fill the bad character array by calling the preprocessing
function badCharHeuristic() for given pattern */
badCharHeuristic(pat, m, badchar);
int s = 0; // s is shift of the pattern with respect to text
while(s <= (n - m))
{
int j = m-1;
/* Keep reducing index j of pattern while characters of
pattern and text are matching at this shift s */
while(j >= 0 && pat[j] == txt[s+j])
j--;
/* If the pattern is present at current shift, then index j
will become -1 after the above loop */
if (j < 0)
{
printf("\n pattern occurs at shift = %d", s);
/* Shift the pattern so that the next character in text
aligns with the last occurrence of it in pattern.
The condition s+m < n is necessary for the case when
pattern occurs at the end of text */
s += (s+m < n)? m-badchar[txt[s+m]] : 1;
}
else
/* Shift the pattern so that the bad character in text
aligns with the last occurrence of it in pattern. The
max function is used to make sure that we get a positive
shift. We may get a negative shift if the last occurrence
of bad character in pattern is on the right side of the
current character. */
s += max(1, j - badchar[txt[s+j]]);
}
}
/* Driver program to test above function */
int main()
{
char txt[] = "ABAAAABAACD";
char pat[] = "AA";
search(txt, pat);
return 0;

How to XOR scramble a string in C and back again with the same function?

I am trying to obfuscate a string in a program. Currently, I only have a simple string reversal working. I would like to be able to perform XOR scrambling on the data to make it much more secure, however the method I have tried is not working.
The same function and input type is used to decode the string. This is no problem with string reversal, as it just reverses back, but can this be done easily with XORing without getting too complex? I would prefer if the process kept just the one string, like the reversal does. Here is my reversal function.
void reverse_string(unsigned char *buf, int length)
{
int i;
unsigned char temp;
for (i = 0; i < length / 2; i++)
{
temp = buf[i];
buf[i] = buf[length - i - 1];
buf[length - i - 1] = temp;
}
}
And here is the attempt at a XOR function
void charxor(char * text, int len) {
const unsigned char enc[8]={173,135,131,121,110,119,187,143};
char ch;
int i;
int ind=0;
for (i=0;i<len;i++) {
ch=*text++;
if (ch)
*text = ch ^ enc[ind++];
ind %=8;
}
}
Can anyone help? Would be much appreciated!
You seem to be overcomplicating things a bit. Try this instead:
void charxor (unsigned char *text, int len) {
const unsigned char enc[8] = {173,135,131,121,110,119,187,143};
int i;
for (i = 0; i < len; i++) {
text[i] ^= enc[i % 8];
}
}
Note that the XOR operation can introduce null chars into the string, so you really do need to keep track of its length instead of just relying on the presence of a trailing null char.
Also keep in mind that, while this may indeed be relatively speaking "much more secure" than just reversing the string, any reasonably clever person with access to enough samples of the output can probably figure out how to decode it in around fifteen minutes or so.
this is a pbox, it would require you to make a non repeating integer key - random - same size as said block. the last block would start with the offset which could be just random data. Doesn't cover null terminators so decide where the data is going / what your doing with it. you could realloc(buff, "A") to use memmove. make 3 64 bit boxes, and a subset of 16 4 bit boxes from the output of the 64 and it starts to look like a poor implementation of des, which openssl has build into it. The fundamental advantage is being able to encrypt/decrypt with the same function / address space. This could also allow you to encrypt in place without a extra buffer. KSZ is the length of your block(s)/key
char
*zecr
(bff, zbf, ky, ze)
char *bff;
char *zbf;
unsigned int ky[];
short ze;
{
/* main encrypt decrypt function */
int i=0;
while( i < KSZ ) {
int dx = ky[i];
if( ze == 1 ) { // encrypt
char c = bff[dx];
sprintf(zbf + i, "%c", c);
} else { // decrypt
char c = bff[i];
char tk[1] = "";
sprintf(tk, "%c", c);
memmove(zbf +dx, tk, 1);
}
i++;
}
return zbf;
}
xoring is a binary operation, which will yield vastly different results depending on how you cast it. You got the right idea using ocdec but if the idea is to keep it simple im going to assume you don't actually know assembly despite the requested reference, stick with c calls its simpler for how you are most likely going to be using the data.
-the female orgasm, that's the myth. -SUN TZU

Resources