How to change code to encrypt instead of decrypting files? - c

I used the code included below to decrypt some graphic files. I would like to modify it so it can encrypt them again. Unfortunately I'm a graphic designer and I only have very basic knowledge about programing (and not in C) so I don't understand this code on a level that would allow me to modify it by myself.
#include <stdio.h>
int main (int argc, char **argv)
{
FILE *inp, *outp;
int i;
char sig[] = "CF10", *ptr;
if (argc != 3)
{
printf ("usage: decode [input] [output]\n");
return -1;
}
inp = fopen (argv[1], "rb");
if (inp == NULL)
{
printf ("bad input file '%s'\n", argv[1]);
return -2;
}
ptr = sig;
while (*ptr)
{
i = fgetc (inp);
if (*ptr != i)
{
printf ("input file sig is not 'CF10'\n");
return -2;
}
ptr++;
}
outp = fopen (argv[2], "wb");
if (outp == NULL)
{
printf ("bad output file '%s'\n", argv[1]);
return -2;
}
do
{
i = fgetc(inp);
if (i != EOF)
fputc (i ^ 0x8d, outp);
} while (i != EOF);
fclose (inp);
fclose (outp);
printf ("all done. bye bye\n");
return 0;
}

This could, at best, be described as obscuring the content. It uses 'xor' encryption, and the one advantage of that is that is self-decrypting.
You can run the code on an unencrypted file and get an encrypted file, or on an encrypted file and get an unencrypted file.
I misread the code; sorry. Your code reads the CF10 magic number, and then writes the rest of the data after xor'ing it; the CF10 tells it that it is obscured. To obscure unobscured data, you should write the CF10 magic number to the output file, then read the input and xor it and write it. A refined version of the code would test the first four bytes of the file (for equality with CF10) to ensure that you are not re-obscuring and already obscured file.
You might need to handle an option argument that determines whether to encrypt or decrypt (obscure or unobscure). Alternatively, you can use the first four bytes of the file to tell you whether to encrypt or decrypt.
Note that the basic point of the original answer — that xor encryption and decryption are fundamentally the same operation — remains valid.

Related

How can I replace letters with numbers in C?

So I want to make kind of an encryption program for a school project,I want for example the letter 'a' to be replaced with:12345 'b' with 54321 in C,how can I accomplish this?I'm not the best,my code so far:
eFile = fopen("Message.txt", "ab+");
while(!feof(eFile))
{
fscanf(eFile,"%c",&message);
}
I want for example if I write the word apple into the text file,make the program scan it letter by letter and replace every letter with a 5 digit number(I have them predefined already) example: apple = 12342 69865 69865 31238 43297
read character by character from input
use simple array to convert between character to number or to string, or use a handler function for that
print that number
replacing is not easy, simplest way is to create a tempfile, write numbers to that tempfile, than copy the tempfile to the original file and remove tempfile.
_
#include <stdio.h>
#include <assert.h>
int cipher_table[255] = {
['a'] = 12342,
['p'] = 69865,
['l'] = 31238,
['e'] = 43297,
// so on...
};
int main()
{
FILE *fin = stdin; // fopen(..., "r");
assert(fin != NULL);
FILE *fout = stdout; // tmpfile();
assert(fout != NULL);
for (int c; (c = getc(fin)) != EOF;) {
if (c == '\n') {
if (fputc('\n', fout) == EOF) {
fprintf(stderr, "Error writing to file fout with fputc\n");
return -1;
}
continue;
}
if (fprintf(fout, "%5d ", cipher_table[c]) < 0) {
fprintf(stderr, "Error writing to file fout with fprintf\n");
return -1;
}
}
close(fin);
close(fout);
return 0;
}
I'm not sure if your strategy can be called encryption, but it can be easily accomplished
with a lookup table.
Simply put the replacements in an int table like so:
int map[]={ //size will be autoinferred to fit the indices
['a']=12342,
['p']=69865,
['l']=31238,
['e']=43297,
//you should preferrably have an entry for each value of char
};
And use it to print the replacements.
int c;
while(EOF!=(c=fgetc(inputFile)))
if(0>(outPutfile,"%d \n", map[c]))
return -1;
Since the size of the new file will unpredictably change, it'd probably
be a good idea to output into a temporary file and then move it in the
place of the original after it's successfully finished.
A better idea might be to simply forget about in-place file rewriting
and simply read stdin and write to stdout – that would allow the program to handle streams well as well and a possibly wrapper script could turn it into an inplace translator (via the temp file) after the fact if needed.

fwrite() appends instead of write C

I have to write a program witch reads from a file received by line and then it overwrites it with the read words uppercased.
This is my code
void toUpperCase(char* string) {
int i=0;
while(string[i])
{
string[i]=toupper(string[i]);
i++;
} }
int main(int argc, char** argv) {
if(argc==1)
{
puts("Error: INSERT PATH");
exit(0);
}
char* file=argv[1];
FILE* fd=fopen(file,"r+");
if(fd<0)
{
perror("Error opening file: ");
exit(0);
}
char buffer[30][30];
int i=0;
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
int j=0;
for(j=0; j<i; j++)
{
toUpperCase(buffer[j]);
fwrite(buffer[j],strlen(buffer[j]),1,fd);
}
fclose(fd);
return 0; }
but this program appends the words contained in buffer[][] instead of overwriting the file.
If the file contain was something like pippo pluto foo then, after the execution is pippo pluto fooPIPPOPLUTOFOO instead of PIPPO PLUTO FOO.
Where am i wrong? Thank you
You have to reset the file position indicator using fseek, as fscanf will advance it. Something like
fseek(fd, length_of_read_string, SEEK_CUR);
This allows you to read the file in chunks, but it will be tricky to get right. Or of course reset it to the file start because you read everything in 1 go:
fseek(fd, 0L, SEEK_SET);
I strongly recommend writing the modified data into a new file, and then after the program has run, delete the initial file and rename the new one. That will also take care of another issue with your program, you are reading the entire file into memory before handling it.
If you want to do in-place translation that doesn't change lengths, you can open the source file in two streams and then do read-chunk, write-chunk in lockstep. That has the advantage of being super-easy to convert to a non-in-place version that will work with nonseekable files too (stdin/stdout, pipes, and sockets).
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h> //toupper
inline void upcaseStr(char* str){
for(;*str;str++) { *str=toupper(*str); }
}
int upcaseStream(FILE* in, FILE* out){
char buf[BUFSIZ]; //BUFSIZ is an implementation-defined constant for an optimal buffer size
while(fgets(buf, BUFSIZ, in)){
upcaseStr(buf);
if(fputs(buf, out) == EOF){ return 1; }
}
if(!feof){ return 1; }
return 0;
}
int main(int argc, char **argv)
{
//default in and out
FILE* in = stdin;
FILE* out = stdout;
if(argc == 2) {
in = fopen(argv[1], "r"); //for reading
out = fopen(argv[1], "r+"); //for writing (and reading) starting at the beginning
if(!(in && out)){
fprintf(stderr, "Error opening file %s for reading and writing: %s\n", argv[1], strerror(errno));
}
}
return upcaseStream(in, out);
}
If you do use the in-place version, then in the unlikely event that the if(fputs(buf, out) == EOF){ return 1; } line should return, you're screwed unless you have a backup copy of the file. :)
Note:
You shouldn't name your FILE pointers fd because C people will tend to think you mean "file descriptor". FILE is a struct around a file descriptor. A file descriptor is just an int that you can use for FILE access with the raw system calls. FILE streams are an abstraction layer on top of file descriptors--they aren't file descriptors.
As you read from the file, its internal position indicator gets moved. Once you start writing, you start writing from that position on, which happens to be at the end of the file. So you effectively append the data to the file.
Rewind the handle to reset the position indicator before writing into the file:
rewind(fp);
On a side note, you are reading the file incorrectly:
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
When you reach the end of the file, fscanf will return an error and not read anything, yet you still increment variable i, as if the read was successful. And then you check feof() for end-of-file, but i was already incremented.
Check feof() and return of fscanf() immediately after calling fscanf():
while(1)
{
int read = fscanf(fd,"%s",buffer[i]);
if( read != 1 )
//handle invalid read
if( feof(fd) )
break;
i++;
}
Think about what happens if the string is longer than 29 characters and/or the file contains more than 30 strings. char buffer[30][30];
Welcome to StackOverflow!
Reopening the stream with fopen with the "w" parameter:
fd=fopen(file, "w");
It opens the file and if there are any contents in the file, it clears them.

fwrite corrupts my text file

I have been tinkering around for days with a program for a class of mine, and I cannot get fwrite to cooperate. I've tried looking at the online resources for fread and fwrite, looked at my professor's examples, and tried time and time again to fix this, but nothing has worked. No matter what I do, fwrite makes it so that my text editor can't detect any kind of character encoding, so I'm presuming that fwrite is either writing memory addresses or garbage values to the file, making it so that I can't read it. The program is simply supposed to write the contents of one file into another.
Here is my code.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
//initialize files
FILE* infile, *outfile;
char* buffer;
int read = 0;
//handle the case of having the wrong number of inputs.
if (argc != 4){
printf("Error: incorrect number of inputs\n");
//returning 1 will tell us that this was an error (as opposed to returning zero)
return 1;
}
else{
//handle the case of not having read acces to file 1
if ( access(argv[1], R_OK) == 1){
printf("Error: you do not have read access to the first file\n");
return 1;
}
else {
//handle the case of not having write access to file 2
if ( access(argv[2], W_OK) == 1){
printf("Error: you do not have write access to the second file\n");
return 1;
}
else{
//handle a bad buffer size (zero or negative number)
if ((int)*argv[3] < 0){
printf("Error: bad input for buffer size.\nBuffer size: %d \n", (int)*argv[3]);
return 1;
}
}
}
//open the files in the correct mode.
infile = fopen(argv[1], "r");
outfile = fopen(argv[2], "w");
buffer = malloc((int)*argv[3]);
while (!feof(infile)){
read = fread (buffer,1,(int)*argv[3],infile);
fwrite(buffer,1,(int)*argv[3],outfile);
}
}
//close files, and deallocate the buffer.
fclose(infile);
fclose(outfile);
free(buffer);
//if we made it here, then that means that our program ran correctly, so return zero.
return 0;
}
This is wrong
(int)*argv[3]
change it to
atoi(argv[3])
and it would be better if you store the value somewhere, and check that it's convertible to integer, something like
int size;
char *endptr;
size = strtol(argv[3], &endptr, 10);
if (*endptr != '\0')
errorNotAnIntegerAbortHere();
buffer = malloc(size);
.
.
.
not that, *argv[3] would be equivalent to argv[3][0] which is just the first character in argv[3].
fread will return less than the no. of requested bytes at EOF.
Change to
if (read)
fwrite(buffer,1,read,outfile);

How to load mruby code from external file in C program?

I'm getting started with mruby. I'm also pretty new to programming in C, so I may not be familiar with many of the basics. I was able to compile the example mruby program which loads the ruby code from a string. Now I would like to load it from an external file. Here's the example code that I'm using:
#include <stdlib.h>
#include <stdio.h>
#include <mruby.h>
static mrb_value my_c_method(mrb_state *mrb, mrb_value value)
{
puts("Called my C method");
return value;
}
int main(void)
{
mrb_state *mrb = mrb_open();
struct RClass *mymodule = mrb_define_module(mrb, "MyModule");
mrb_define_class_method(mrb, mymodule, "my_c_method", my_c_method, MRB_ARGS_NONE());
mrb_load_string(mrb, "MyModule.my_c_method"); // move this to an external file
return 0;
}
As you can see in the example above, I would like to move the ruby code to an external file. I'm a little confused as to whether or not I can simply "include" the ruby file, or if I need to precompile it into an .mrb file. Even then I'm not sure how to include that .mrb file when compiling.
What do I need to change to be able to load the ruby code from an external file?
Assuming your code is stored in file foo, all you need is to open the file and read it. To open the file, you need fopen(), defined in stdio.h. You can then read it line by line using fgets(). I'm not familiar with mruby, so I'm not exactly sure if mrb_load_string expects that every mruby code is in a single line. I will assume so. Here's how you can do it:
#define MAX_CODE_SIZE 128
FILE *code;
char code_buf[128]
code = fopen("foo", "r");
if (code == NULL) {
/* File couldn't be opened, handle error case... */
}
fgets(code_buf, MAX_CODE_SIZE, code);
/* Do some work ... */
fclose(code); /* Don't forget to close the file */
This piece of code reads the first line of file foo, up to a limit of 127 characters (including newline), and stores it in code_buf. You can then call mrb_load_string:
mrb_load_string(mrb, code);
I'm not sure if this is what you wanted, I never touched mruby, but from what I saw, mrb_load_string expects a char * with the code, and you want that to come from a file. That's how you do it.
If you want to read a file with code in multiple lines, you have no choice but to allocate a large enough buffer and read it using fread():
#include <stdio.h>
#define MAX_LINE_LENGTH 128
#define MAX_LINES 256
#define MAX_FILE_SIZE MAX_LINE_LENGTH*MAX_LINES
char code[MAX_FILE_SIZE];
int read_code(char *filepath) {
FILE *fp = fopen(filepath, "r");
if (fp == NULL)
return 0;
fread(code, 1, MAX_FILE_SIZE, fp);
fclose(fp);
return 1;
}
This function reads the whole file (assuming it doesn't exceed our buffer limits). code is global because you can easily reach the stack capacity if you allocate large local variables (another alternative is to use dynamic allocation). When you call read_code(), you should make sure to check its return value, to check for possible errors upon opening the file. Also, you can play with fread()'s return value to know if the buffer size wasn't enough to read everything.
Just make sure you don't forget to close the file when you're done.
EDIT: For the fgets() version, please note that in case the line holds less than 128 characters, newline will be retained in code_buf. You may want to set code_buf[strlen(code_buf)-1] to '\0' if that's the case.
UPDATE:
From our discussion on the comments below, I am updating my answer with a rudimentary parser to enable you to read the ruby file at compile time. Basically, the parser will read your ruby file and generate an output file with valid C code that inserts the file's content in a char array. Special characters are accordingly escaped. Here it is:
#include <stdio.h>
void inline insert(int, FILE *);
int main(int argc, char *argv[]) {
FILE *out, *in;
int c;
if (argc != 3) {
printf("Usage: %s <input_file> <output_file>\n", argv[0]);
return 1;
}
in = fopen(argv[1], "r");
out = fopen(argv[2], "w");
if (out == NULL) {
printf("Unable to create or write to %s\n", argv[1]);
return 1;
}
if (in == NULL) {
printf("Unable to read %s\n", argv[1]);
return 1;
}
fputs("#ifndef MRUBY_CODE_FILE_GUARD\n", out);
fputs("#define MRUBY_CODE_FILE_GUARD\n", out);
fputs("char mruby_code[] = \"", out);
while ((c = getc(in)) != EOF)
insert(c, out);
fputs("\";\n", out);
fputs("#endif\n", out);
fclose(in);
fclose(out);
return 0;
}
void inline insert(int c, FILE *fp) {
switch (c) {
case '\a':
fputs("\\a", fp);
break;
case '\b':
fputs("\\b", fp);
break;
case '\f':
fputs("\\f", fp);
break;
case '\n':
fputs("\\n", fp);
break;
case '\r':
fputs("\\r", fp);
break;
case '\t':
fputs("\\t", fp);
break;
case '\v':
fputs("\\v", fp);
break;
case '\\':
fputs("\\\\", fp);
break;
case '\'':
fputs("\\'", fp);
break;
case '"':
fputs("\\\"", fp);
break;
default:
fputc(c, fp);
}
}
Now, go back to your original program and add the following include directive in the beginning:
#include mruby_code.h
You have to do the following steps to compile a runnable program, assuming that this parser was compiled into a file named fileparser.c:
Run ./fileparser /path/to/mruby_code_file /path/to/program/mruby_code.h.
Compile your original program (it will include mruby_code.h)
The mruby code is provided in a variable called mruby_code. This is a char array, so you can pass it to mrb_load_string. And voila, you got the mruby file read once at compile time.
In the mruby/compile.h there is a method called mrb_load_file which allows you to load a ruby file and execute it with mruby:
#include <stdlib.h>
#include <stdio.h>
#include <mruby.h>
#include <mruby/compile.h>
static mrb_value my_c_method(mrb_state *mrb, mrb_value value)
{
puts("Called my C method");
return value;
}
int main(void)
{
mrb_state *mrb = mrb_open();
struct RClass *mymodule = mrb_define_module(mrb, "MyModule");
mrb_define_class_method(mrb, mymodule, "my_c_method", my_c_method, MRB_ARGS_NONE());
FILE *f = fopen("example.rb", "r");
mrb_load_file(mrb, f);
return 0;
}
Apart from using mrb_load_file:
FILE *f = fopen("the_file.rb", "r");
mrb_load_file(mrb, f);
fclose(f) ;
The manual option is to read the filename:
int load_ruby_file_to_state(char *filename, mrb_state *state) {
FILE *file = fopen(filename, "r") ;
if (!file) return -1 ;
fseek(file, 0, SEEK_END);
unsigned long length = ftell(file) ;
fseek(file, 0, SEEK_SET);
char *code = malloc(length + 1) ;
if (code) {
fread(code, 1, length, file) ;
code[length + 1] = '\0' ;
} else {
return -1 ;
}
fclose(file) ;
mrb_load_string(state, code) ;
free(code) ;
return 0 ;
}
And load file: load_ruby_file_to_state("the_file.rb", mrb) ;
Do note that mrb_load_file() will give a segfault if the file doesn't exist, so it's better to check for the file existence or if it's readable.

feof wrong loop in c

I use below code to read a char from file and replace it with another,
but I have an error.loop in going to end of file.
What is wrong?
I tested this code on linux (netbeans IDE) and it was correct and worked beautiful but when I tried to use VS 2008 in windows , I found a non end loop.
//address = test.txt
FILE *fp;
fp=fopen(address,"r+");
if(fp == 0)
{
printf("can not find!!");
}
else
{
char w = '0'; /// EDIT : int w;
while(1)
{
if((w = fgetc(fp)) != EOF)
{
if((w = fgetc(fp)) != EOF)
{
fseek(fp,-2,SEEK_CUR);
fprintf(fp,"0");
}
}
else
{
break;
}
}
}
fclose(fp);
You are storing the result of fgetc in a char, instead of an int.
char w = '0'; /* Wrong, should be int. */
Incidentally, this problem is mentioned in the C FAQ.
If type char is unsigned, an actual
EOF value will be truncated (by having
its higher-order bits discarded,
probably resulting in 255 or 0xff) and
will not be recognized as EOF,
resulting in effectively infinite
input.
EDIT
Reading your question again, it's highly fishy the way you seek back two characters and write one character. That could well lead to an infinite loop.
EDIT2
You (likely) want something like this (untested):
while ((w = getc(fp)) != EOF) {
fseek(fp, -1, SEEK_CUR);
fprintf(fp, "0");
fflush(fp); /* Apparently necessary, see the answer of David Grayson. */
}
The fopen documentation on cplusplus.com says:
For the modes where both read and
writing (or appending) are allowed
(those which include a "+" sign), the
stream should be flushed (fflush) or
repositioned (fseek, fsetpos, rewind)
between either a reading operation
followed by a writing operation or a
writing operation followed by a
reading operation.
We can add an fflush call after the fprintf to satisfy that requirement.
Here is my working code. It creates a file named example.txt and after the program exits that file's contents will be 000000000000n.
#include <stdio.h>
int main(int argc, char **argv)
{
FILE * fp;
int w;
fp = fopen("example.txt","w");
fprintf(fp, "David Grayson");
fclose(fp);
fp = fopen("example.txt","r+");
while(1)
{
if((w = fgetc(fp)) != EOF)
{
if((w = fgetc(fp)) != EOF)
{
fseek(fp,-2,SEEK_CUR);
fprintf(fp,"0");
fflush(fp); // Necessary!
}
}
else
{
break;
}
}
fclose(fp);
}
This was tested with MinGW in Windows.

Resources