am trying to implement an application that uses an MD5 hash underneath, i have acquired the MD5 hash program from the internet, but i don't know how to pass the string from my program ( my program written in C) to the program that calculate the MD5 hash.
this is the main of the program that calculate the MD5 hash..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <stdio.h>
#include <string.h>
#include "winmd5.h"
HCRYPTPROV hCryptProv;
int main(int argc, char *argv[])
{
int i;
CryptStartup();
if(argc > 1){
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)argv[1], strlen(argv[1]));
MD5Final(&ctx);
for(i = 0; i < 16; i++)
printf("%02x", ctx.digest[i]);
printf("\n");
}else
printf("Usage: %s <string>\n", argv[0]);
CryptCleanup();
return 0;
}
this is the header file content..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern HCRYPTPROV hCryptProv;
void PrintMD5(const char *);
typedef struct {
unsigned char digest[16];
unsigned long hHash;
} MD5Context;
BOOL CryptStartup()
{
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) == 0){
if(GetLastError() == NTE_EXISTS){
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0) == 0){
return FALSE;
}
}
else return FALSE;
}
return TRUE;
}
void CryptCleanup()
{
if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
}
void inline MD5Init(MD5Context *ctx)
{
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
}
void inline MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned len)
{
CryptHashData(ctx->hHash, buf, len, 0);
}
void inline MD5Final(MD5Context *ctx)
{
DWORD dwCount = 16;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, ctx->digest, &dwCount, 0);
if(ctx->hHash) CryptDestroyHash(ctx->hHash);
ctx->hHash = 0;
}
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.hHash[i]);
}
printf("\n");
}
how should i call this Main(), and how to pass the String to it and get the result.?
thanks in advance.
Regards
You don't call main() again. You rather use this program as an example to write a separate function, like this:
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.digest[i]);
}
printf("\n");
}
Then you can call this from your own program like:
PrintMD5("FooBarHelloWorld42");
Related
I'm writing a program that implements the Alberti Cipher, and when testing, the final print always gives a string of jargon before the actual encryption. Right now its printing \x80\x16G\xbf\xfe\x7fKHOORZRUOG, with KHOOR..... being the actual encryption. Any help appreciated :)
#include <stdio.h>
#include <stdlib.h>
int letterToNumber(char letter){
char str[2] = { letter };
int num = strtol( str, NULL, 36 ) - 10;
return num;
}
int getSize (const char * s) {
const char * t;
int size = 0;
for (t = s; *t != '\0'; t++) {
size++;
}
return size;
}
char numToChar(int numInp){
numInp=numInp+65;
char returnChar=(char)numInp;
return returnChar;
}
void encrypt_alberti(const char *message,const char *inner_ring, int initialShift,int periodicShift,int periodLength,char **result){
//sets initial shift
int numArray[25];
int count=0;
int shiftCount=0;
for(int i = 0; i < 26; ++i) {
numArray[i]=(i+initialShift)%26;
}
//encrypts each character and prints
int messageSize=getSize(message);
char encryptedMessage[messageSize];
for(int i=0; i<messageSize;i++){
count++;
if(periodicShift!=0){
if(count%periodicShift==0){
shiftCount++;
}
}
else{
periodLength=0;
}
char toBeEncrypted=message[i];
int charNumber=letterToNumber(toBeEncrypted);
int encryptedNum=numArray[(charNumber+(shiftCount*periodLength))%26];
char encryptedChar=numToChar(encryptedNum);
strncat(encryptedMessage, &encryptedChar, 1);
}
char* p1=malloc(sizeof(encryptedMessage));
strcpy(p1,encryptedMessage);
*result=p1;
}
void main(void) {
const char *example_message = "HELLOWORLD";
const char *example_inner = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *encrypted_message = NULL;
encrypt_alberti(example_message, example_inner, 3, 0, 1, &encrypted_message);
printf("message is %s\n", encrypted_message);
printf("-----------------");
free(encrypted_message);
}
}
I'm trying to implement reading the BMP file in c.
I came across basic bmp reading module from google as the below.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
But I feel hard to use above function in my code.
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
When I do implement like this I've got a error message as the below
error C4700: uninitialized local variable 'ret_bmp_data' used
How do I initialize the local variable?
update
I've updated ReadBMP.c file at all.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data)
{
char *byte_data;
int offset;
byte_data = (char *)bmp_file_data;
if ((byte_data[0] != 'B') || (byte_data[1] != 'M'))
{
return -1;
}
memcpy(&offset, &byte_data[10], 4);
DecodeInfomation(byte_data, offset, ret_bmp_data);
DecodeData(byte_data, offset, ret_bmp_data);
return 0;
}
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
if (offset == 26)
{
memcpy(&ret_bmp_data->width, &byte_data[18], 2);
memcpy(&ret_bmp_data->height, &byte_data[20], 2);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[24], 2);
}
else
{
memcpy(&ret_bmp_data->width, &byte_data[18], 4);
memcpy(&ret_bmp_data->height, &byte_data[22], 4);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[28], 2);
}
}
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
int data_size;
if (ret_bmp_data->bits_per_pixel == 24)
{
data_size = ret_bmp_data->width * ret_bmp_data->height * 3;
ret_bmp_data->data = malloc(data_size);
memcpy(ret_bmp_data->data, &byte_data[offset], data_size);
}
}
this is ReadBMP.h
#ifndef READBMP_H
#define READBMP_H
typedef struct BMPDATA
{
short bits_per_pixel;
int width;
int height;
unsigned char *data;
}BMPDATA;
#ifdef __cplusplus
extern "C"
{
#endif
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data);
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data);
#ifdef __cplusplus
}
#endif
#endif
and
this is Source.cpp
#include <stdio.h>
#include <stdlib.h> /* system, NULL, EXIT_FAILURE */
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
////////////////// add BMP read 2018-03-20 ///////////////
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
fclose(fp);
fclose(fp_new);
}
Due to the error message, it seems that the BMPDATA variable in main isn't supposed to be a BMPDATA pointer but a BMPDATA object.
Like:
int main(int argc, char *argv[])
{
....
BMPDATA ret_bmp_data;
....
ReadBMPFile(filename_new, &ret_bmp_data);
....
}
I've made a queue header file and I've tried to use it with threads.
What I'm doing is making 2 threads, 1 for reading the characters from the code file and entering the characters to the queue and the other thread is trying to print the characters to the console.
The problem is that no characters are being printed to the console and I can't figure out why.
queue.h :
#ifndef QUEUE_INT
#define QUEUE_INT
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
int *elementData;
unsigned int queueSize;
unsigned int capacityIncrement;
unsigned int elementCount;
} Queue;
void queue_initialize(Queue*, unsigned int);
int queue_add(Queue*, int);
void queue_poll(Queue*);
int queue_peek(const Queue*);
void queue_destroy(Queue*);
bool queue_isEmpty(const Queue*);
void queue_setCapacityIncrement(Queue*, unsigned int);
unsigned int queue_getCapacityIncrement(const Queue*);
unsigned int queue_getNumberOfElements(const Queue*);
unsigned int queue_getSize(const Queue*);
void queue_initialize(Queue *p, unsigned int capacityIncrement)
{
p->elementData = NULL;
p->queueSize = 0;
p->capacityIncrement = capacityIncrement;
p->elementCount = 0;
}
int queue_add(Queue *p, int value)
{
if(p->elementCount == p->queueSize)
{
int newQueueSize = p->queueSize + p->capacityIncrement;
void *temp = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
if(temp == NULL || newQueueSize == 0)
{
return 1;
}
p->queueSize = newQueueSize;
p->elementData = temp;
}
p->elementData[p->elementCount] = value;
p->elementCount++;
return 0;
}
void queue_poll(Queue *p)
{
if(!queue_isEmpty(p))
{
p->elementCount--;
if(p->queueSize - p->elementCount == p->capacityIncrement / 2 + p->capacityIncrement)
{
int newQueueSize = p->queueSize - p->capacityIncrement;
p->elementData = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
p->queueSize = newQueueSize;
}
for(int i = 0; i < p->elementCount; i++)
{
p->elementData[i] = p->elementData[i + 1];
}
}
}
int queue_peek(const Queue *p)
{
if(!queue_isEmpty(p))
{
return p->elementData[0];
}
return 0;
}
void queue_destroy(Queue *p)
{
free(p);
}
bool queue_isEmpty(const Queue *p)
{
return p->elementCount == 0;
}
void queue_setCapacityIncrement(Queue *p, unsigned int capacityIncrement)
{
p->capacityIncrement = capacityIncrement;
}
unsigned int queue_getCapacityIncrement(const Queue *p)
{
return p->capacityIncrement;
}
unsigned int queue_getNumberOfElements(const Queue *p)
{
return p->elementCount;
}
unsigned int queue_getSize(const Queue *p)
{
return p->queueSize;
}
#endif
Code file :
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include <time.h>
#include "queue.h"
bool isFillQueueThreadRunning;
bool isQueueProcessing;
void fillQueueThread(void*);
void popQueueThread(void*);
int main()
{
srand(time(NULL));
Queue q1;
queue_initialize(&q1, 4);
HANDLE hFillQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
HANDLE hPopQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
WaitForSingleObject(hFillQueueThread, 1000 * 300);
WaitForSingleObject(hPopQueueThread, 1000 * 300);
return 0;
}
void fillQueueThread(void *p)
{
isFillQueueThreadRunning = true;
Queue *q = (Queue*)p;
FILE *f = fopen(__FILE__, "r");
int b;
while((b = getc(f)) != EOF)
{
Sleep(rand() % 50);
while(isQueueProcessing)
{
}
isQueueProcessing = true;
if (queue_add(q, b) == 1)
{
break;
}
isQueueProcessing = false;
}
fclose(f);
isFillQueueThreadRunning = false;
}
void popQueueThread(void *p)
{
Queue *q = (Queue*)p;
Sleep(10);
int b;
while(isFillQueueThreadRunning || q->elementCount > 0)
{
while(isQueueProcessing)
{
}
isQueueProcessing = true;
b = queue_peek(q);
queue_poll(q);
putchar(b);
isQueueProcessing = false;
}
}
you _beginthread the fillQueueThread twice.
and
you never initialize isFillQueueThreadRunning reliably. Code may depend on uninitialized variable.
from what I've seen
Your queue implementation is far from thread safe. As Joachim mentioned, please education yourself with thread synchronization primitives. A simple mutex would go a long way here.
See: What is a mutex?
As to your large blocks of spaces, you use the output of queue_peek() unconditionally which can (and will frequently) be NULL.
Do you know that the result of putchar(NULL) is?
Here is a snippet of my code:
#include <stdio.h>
#include "uhash.h"
#include <openssl/evp.h>
char * hash(item a)
{
const char * str= a.k;
int len= strlen(str);
int md_len;
unsigned char md_value[EVP_MAX_MD_SIZE]; /* Buff to store change result */
EVP_MD_CTX *mdctx; /* Digest data structure declaration */
const EVP_MD *md;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("SHA256");
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, str, len);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
char md5str[33];
for(int i=0;i<md_len;++i)
{
sprintf(&md5str[i*2],"%02x",(unsigned int)md_value[i]);
}
printf("%s\n", md5str);
return md5str;
}
int main(int argv, char **argc)
{
char *c;
if (argv>0)
{
int i=0;
int s=0;
for(i=1;i<argv;i++)
{
s+=strlen(argc[i]);
}
c=(char *)(malloc(sizeof(char)*s*(argv-2)+1));
s=0;
for(i=1;i<argv;i++)
{
char *t=c+s;
memcpy(t,argc[i],strlen(argc[i]));
if(i!=argv-1){
printf("%d\n", argv);
t[strlen(argc[i])]=' ';
s++;
}
s+=strlen(argc[i]);
}
*(c+s)='\0';
}
printf("%s\n", c);
item * kee= malloc(sizeof(item));
kee->k=c;
kee->v=10;
char *res= hash(*kee);
fflush(stdout);
if(res==NULL)
printf("result is null...");
else
printf("%s\n",res);
fflush(stdout);
}
So the main function takes the arguments fine(tested) and passes it fine(tested) but the hash() function although computing the hash, does not either return the right value or I can't print the result in main. I've been trying to check for errors since yesterday but I'm not very smart so any help would be greatly appreciated!
Root cause: You are returning something that has been created on the stack and once it returns it is wiped. res is pointing into your stack.
Fix: Put the declaration of md5str outside the routine hash or make it static within the routine hash.
Im making an application that uses of API-threads in C, The program takes N-files (N>2) with names disordered,per each file is generated a thread of execution which sort the files using the function qsort, after being ordered files, each thread should create a file keeping the original file intact and displaying the sorted file to another file with the extension <.sorted>. The program sorts the numbers without problems, even if I put standard output displays the result on screen, but when I try to create the output file with extension .sorted the program breaks out.
this is my code file.c
#include <stdio.h> /* Standard buffered input/output */
#include <stdlib.h> /* Standard library functions */
#include <string.h> /* String operations */
#include <pthread.h> /* Thread related functions */
#include "pf1.h" /* Header specific to this app */
pthread_attr_t attr;
void *thread_worker(void *name_file)
{
FILE *entrada, *salida;
char* nombres = (char*)name_file;
int numero;
char temp [10000];
int i;
stats_t estadisticas;
printf ("File_name:%s\n", nombres);
entrada = fopen(nombres, "r");
salida = fopen (strcat(nombres, ".sorted"), "w");
while (!feof(entrada)){
fscanf (entrada, "%s\n",temp);
numero++;
}
char* lista[numero]; //array to sort the file
rewind (entrada);
for (i=0;i<numero;i++)
{
fscanf(entrada," %[^\n]", temp);
lista[i] = (char*)malloc((strlen(temp)+1)*sizeof(char));
strcpy(lista[i], temp);
}
size_t large = sizeof(lista) / sizeof(char *);
qsort(lista,large ,sizeof(char *) ,cstring_cmp );
printf ("Archivo Ordenado\n", i+1);
for (i=0;i<large;i++)
printf("%s\n",lista[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv [])
{
stats_t **stats;
int i, rc;
pthread_t my_threads[argc-1];
pthread_attr_init(&attr);
if (argc <3) {
printf ("|files| > 2\n");
}else{
printf("files to sorted: %d\n", argc - 1);
for (i = 1; i < argc; i++){
//printf("%s%s\n", argv[i], (i < argc-1) ? " " : "");
rc = pthread_create(&my_threads[i], &attr, thread_worker, (void *)argv[i]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n",rc);
return -1;
}
}
}
return 0;
} /*end main */
this is mi file.h
#ifndef PF1_H_
#define PF1_H_
typedef struct _stats_t
{
char *longest, *shortest;
unsigned int numlines;
} stats_t;
int cstring_cmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return -strcasecmp(*ia, *ib);
/* strcmp functions works exactly as expected from
comparison function */
}
void print_cstring_array(char **array, size_t len)
{
size_t i;
for(i=0; i<len; i++)
printf("%s | ", array[i]);
putchar('\n');
}
#endif /* PF1_1_H_ */
I would like some help with this problem because I can not see which is the fault ... thanks to all in advance and excuse my English
This line here may be your problem:
salida = fopen (strcat(nombres, ".sorted"), "w");
From what I can tell, that nombres variable is coming from argv. Since you're not the one allocating memory for argv, you don't know that there will be extra space for the ".sorted" (and there probably won't be). If you strcpy it to your own buffer with space for the ".sorted", you should be fine.
#define EXT_LEN 7
#define MAX_TOTAL_LEN 250
#define MAX_FILE_LEN 242 //MAX_TOTAL_LEN - EXT_LEN - 1
char *name_ptr;
char nombres[MAX_TOTAL_LEN];
int len;
name_ptr = (char*)name_file;
len = strlen(name_ptr);
if (len > MAX_FILE_LEN) {
len = MAX_FILE_LEN;
}
strncpy(nombres, name_ptr, len);
strcpy(nombres+len, ".sorted");
salida = fopen (nombres, "w");
I once had issues about not passing an int identifier while calling thread execution functions. Try building a struct with both an integer identifier and the filename, then pass it as a parameter to your thread_worker() function.