I'm trying to read a JPG image file and convert it to string of hex code (not hex of pixel) in C.
Something like:
FFD8FFE000114A464946000102030405060708090AFFDB00....
I tried many way but not working. Someone has any idea?
My code which I tried with stb libraries: https://codeload.github.com/nothings/stb/zip/master
// USAGE: gcc -std=c99 image.c -o image -lm
#include <stdio.h>
#include <math.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
const size_t NUM_PIXELS_TO_PRINT = 10U;
int main(void) {
int width, height, comp;
unsigned char *data = stbi_load("r3.jpg", &width, &height, &comp, 0);
if (data) {
printf("width = %d, height = %d, comp = %d (channels)\n", width, height, comp);
for (size_t i = 0; i < NUM_PIXELS_TO_PRINT * comp; i++) {
printf("%02x%s", data[i], ((i + 1) % comp) ? "" : "\n");
}
printf("\n");
}
return 0;
}
The error I got when try with John Smith:
ImageProcess.c: In function ‘main’:
ImageProcess.c:14:5: warning: implicit declaration of function ‘bzero’ [-Wimplicit-function-declaration]
bzero(data, fsize + 1);
^
ImageProcess.c:18:5: warning: implicit declaration of function ‘hexlifyn’ [-Wimplicit-function-declaration]
char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
^
ImageProcess.c:18:48: error: ‘uint’ undeclared (first use in this function)
char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
^
ImageProcess.c:18:48: note: each undeclared identifier is reported only once for each function it appears in
ImageProcess.c:18:53: error: expected ‘)’ before ‘fsize’
char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
^
ImageProcess.c: At top level:
ImageProcess.c:21:28: error: unknown type name ‘uint’
char *hexlifyn(char *bstr, uint str_len) {
^
If your goal is to get the contents of a file as hex string than that should work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main() {
char* file_name = "/path/to/any.png";
FILE *f = fopen(file_name, "rb");
if (f==NULL) return;
fseek(f, 0, SEEK_END);
size_t fsize = ftell(f);
fseek(f, 0, SEEK_SET);
void*data = malloc(fsize + 1);
bzero(data, fsize + 1);
fread(data, 1, fsize, f);
fclose(f);
char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
}
char *hexlifyn(char *bstr, uint str_len) {
char *hstr=malloc((str_len*2)+1);
bzero(hstr,(str_len*2)+1);
char *phstr=hstr;
for(int i=0; i<str_len;i++) {
*phstr++ =v2a((bstr[i]>>4)&0x0F);
*phstr++ =v2a((bstr[i])&0x0F);
}
*phstr++ ='\0';
return hstr;
}
char v2a(int c) {
const char hex[] = "0123456789abcdef";
return hex[c];
}
From your comment I understand that you want to retrieve the binary contents of a file (i.e. a JPG image) as a hexadecimal string.
What you're looking for is something called "hex dump". There are various libraries and snippets available that allow doing this with C.
This stackoverflow question addresses exactly this issue.
This will give you image file output as a continuous hex string in your terminal as well as a .txt file:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
string myText;
int main()
{
system("xxd -p image.jpg > image.txt | tr -d '\n'");
ifstream MyReadFile("./image.txt");
while (getline (MyReadFile, myText)) {
// Output the text from the file
cout << myText;
}
MyReadFile.close();
return 0;
}
Related
I am trying to compile a C program using MinGW on Windows 7 (64-bit). The code is given below:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
void readRegDwordValue() {
HKEY hKey = HKEY_LOCAL_MACHINE;
char const *subKey = "Software\\Metpl\\My Program";
char const *pValue = "MJP_XXX";
uint32_t flags = RRF_RT_REG_DWORD;
int *pvData = NULL;
int64_t result = RegGetValue(hKey, &subKey, pValue, flags, NULL, pvData, sizeof(DWORD));
if (result != ERROR_SUCCESS) {
printf("Error getting value. Code: ");
printf("%" PRId64 "\n", result);
} else {
printf("Value data: ");
printf("%" PRId32 "\n", *(int32_t*)pvData);
}
}
int main() {
readRegDwordValue();
return 0;
}
I get the following warning:
gcc -O3 -Wall -c -o readReg.o readReg.c
readReg.c: In function 'readRegDwordValue':
readReg.c:13:22: warning: implicit declaration of function 'RegGetValue'; did you mean 'RegSetValue'? [-Wimplicit-function-declaration]
13 | int64_t result = RegGetValue(hKey, &subKey, pValue, flags, NULL, pvData, sizeof(DWORD));
| ^~~~~~~~~~~
| RegSetValue
I have included windows.h which includes winreg.h that contains the definition of the RegGetvalue function. Why is the compiler not able to find it? Also, since it is suggesting that I meant RegSetValue, does it mean it is able to find this one? !!
The linker gives the following error:
gcc readReg.o -o readReg.exe -L -liphlpapi -ladvapi32
d:/__sdk/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: readReg.o:readReg.c:(.text+0x45):
undefined reference to `RegGetValue'
collect2.exe: error: ld returned 1 exit status
What am I missing here? I have been pulling my hair over this for over 8 hours now and not able to understand where I am making the mistake. I have not been able to find much relevant discussion online on this either.
Desperately request some input on this so that I can move forward. Thanks in advance.
Finally! All the hair-pulling bore fruit. And, all the peripheral learning along the journey now seems exhilarating. Following is what works with MinGW-w64 (32-bit):
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
char buffer[1024]; // Based on need. This is the max that I need.
DWORD bufferSize = sizeof(buffer);
DWORD readRegDwordValue(HKEY hKey, char const *subKey, char const *pValue) {
long unsigned int *p = NULL;
int64_t result = RegGetValue(hKey, subKey, pValue, RRF_RT_REG_DWORD, p, &buffer, &bufferSize);
if (result != ERROR_SUCCESS) {
return 4294967295; // max unsigned int.
}
return ((DWORD *)buffer)[0]; // return the first element of the buffer.
}
char * readStringValue(HKEY hKey, char const *subKey, char const *pValue) {
long unsigned int *p = NULL;
int64_t result = RegGetValue(hKey, subKey, pValue, RRF_RT_REG_SZ, p, &buffer, &bufferSize);
if (result != ERROR_SUCCESS) {
return "Error";
}
return (char *)buffer;
}
int main() {
char *string = readStringValue(HKEY_LOCAL_MACHINE, "Software\\Metpl\\My Program", "companyName");
printf("string:%s%s%d%s \n", string, " (length = ", strlen(string), ")");
DWORD integerValue = readRegDwordValue(HKEY_LOCAL_MACHINE, "Software\\Metpl\\My Program", "sampleInteger");
printf("integer:(%lu%s\n", integerValue, ")");
return 0;
}
I have tested this code and it gives correct results. Since I only need to get the correct result or an error, I have not added additional error-checking in the code.
Thanks, #CGio3, for pointing me to MinGW-w64. I have made many Portable C programs and a few Windows programs with the version I have and got too comfortable with it, I guess. Anyway, lesson learnt.
Hope this helps someone who has been struggling with the subject.
I have a header file containing:
extern char *finalLoggerPath;
I am trying to implement a function that can initialize or modify the finalLoggerPath variable.
My main function indirectly calls a function defined in a second file. This second function generates a path which does not yet exist, and saves it in two file-scope variables, finalPath and finalLoggerPath. After that is done, I would like another function defined in a third file to be able to print the finalLoggerPath.
I have attempted to implement this, but I get an error:
Memory access error (memory dump used)
How can I fix my program?
My code:
// First File
void initLog() {
generateFileNameWithDate();
}
int main(void) {
initLog();
}
// Second File
#define PATHTEST "../TestLogSystem/"
#include "Info.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
char pathToFile[100] = "../TestLogSystem/";
char *actual;
char *finalPath;
char *finalLoggerPath;
int generateFileNameWithDate() {
int counter = 1;
char filename[999];
char filenameBuffer[999];
int notCreatetFile = 1;
char counterS[999];
time_t now = time(NULL);
if (now == -1) {
puts("The time() function failed");
return 1;
}
struct tm *ptm = localtime(&now);
if (ptm == NULL) {
puts("The localtime() function failed");
return 1;
}
strftime(filename, sizeof(filename),
strcat(strcat(pathToFile, "%Y%m%d"), ".json"), ptm);
while (notCreatetFile) {
if (access(filename, F_OK) != -1) {
// file exists
memset(filename, 0, sizeof(filename));
memset(pathToFile, 0, sizeof(pathToFile));
sprintf(pathToFile, "%s", PATHTEST);
memset(filenameBuffer, 0, sizeof(filenameBuffer));
sprintf(counterS, "%d", counter);
strftime(filename, sizeof(filename),
strcat(
strcat(
strcat(
strcat(strcat(pathToFile, filenameBuffer),
"%Y%m%d"), "-Test-"),
counterS), ".json"), ptm);
} else {
// file doesn't exist
finalPath = malloc(strlen(filename) + 1);
printf("finalPath: %s \n", finalPath);
strcpy(finalPath, filename);
strcpy(finalLoggerPath, finalPath);
fopen(finalPath, "w");
notCreatetFile = 0;
}
++counter;
}
return 0;
}
// Third File
#include "Info.h"
void print() {
printf("FinalLoggerPath: %s", finalLoggerPath);
}
I compile it:
gcc CallFileExists.c FileExists.c GetVariableFromFileExists.c
I cannot compile a C file that contain a function-call of a function, which is in another file. The compilation gives an error which says that there is an undefined reference even if I included the relative path to the Header file in the compilated file.
#include <stdio.h>
#include "../libft.h"
void *ft_memmove(void *dest, const void *src, size_t n)
{
unsigned char *d;
unsigned char *s;
size_t i;
d = (unsigned char *)dest;
s = (unsigned char *)src;
i = 0;
if (s < d)
{
while (n--)
d[n] = s[n];
}
else
ft_memcpy(d, s, n);
return (d);
}
int main()
{
char str[] = "memmove can be very useful.....";
ft_memmove (str+20, str+15, 11);
puts (str);
return (0);
}
The error that I get : gcc complier error
The header file : the header file
Can you help me please to resolve this problem ?
I'm trying to be able to decode encoded strings that were encoded using a perl script. The reason I can't just change the perl script is because a lot of important data already exists that was saved via the perl script and it would be too much to decode in perl and recode another way. It's easier just to keep things in place (for now). However, the compiled perl code is 2MB. I want to write it in C so the executable will be a smaller size.
What I have so far is below. It won't work though. It basically gives me junk output. The problem I think is that the perl script used a hex-based encryption. How do I go about decoding that? Can someone point me to where I went wrong?
/*
Test to decode perl-encrypted string.
NOTE: Not all code written by me. Function code is either written by or derived
from code from other people in response to similar questions found on the
internet.
Required Lib: crypt (-lcrypt)
Perl Code from existing script (that is being converted to C):
use Crypt::CBC;
use Crypt::DES;
my $text = "thisisalongtest";
my $salt_key = "fOagmJOKu2SF";
my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
my $enc_text = $cipher->encrypt_hex($text);
Perl crypt functions require libcrypt-cbc-perl & libcrypt-des-perl
Data:
Original Text: thisisalongtest
Salt Key: fOagmJOKu2SF
Resulting Encrypted String: 53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1
Resulting output:
Decrypted: (unprintable junk characters)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>
#define BUFFSIZE 420
int encrypt(char key[9], char salt[9], char pass[BUFFSIZE], int mode);
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]);
int hex_to_int(char c);
int hex_to_ascii(char c, char d);
int main (int argc, char *argv[]) {
int err;
char passwd[BUFFSIZE];
char result[BUFFSIZE];
char key[13];
sprintf(key,"fOagmJOKu2SF");
/* Change this from hex pairs to ASCII */
sprintf(passwd, "53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1");
enc_from_hex(passwd, result);
/* Decrypt */
err = encrypt(key, "", result, 1); /* DO NOT use 'NULL' for 2nd parameter! */
if(err != 0) {
printf("Error.\n");
} else {
printf("Decrypted: %s\n", result);
}
return 0;
}
/* Encryption */
int encrypt(char key[13], char salt[13], char pass[BUFFSIZE], int mode){
char temp[13];
strcpy(temp, salt);
int buffsize;
int errcode;
des_setparity(key);
buffsize = strlen(pass);
/* Pad pass to ensure size is divisable by 8.*/
while (buffsize % 8 && buffsize<BUFFSIZE) {
pass[buffsize++] = '\0';
}
/* Determine Function */
if(mode == 1) {
errcode = cbc_crypt(key, pass, buffsize, DES_DECRYPT | DES_SW, temp);
} else {
errcode = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, temp);
}
if (DES_FAILED(errcode) || strcmp(pass, "") == 0) {
return errcode;
}
return errcode;
}
/* Hex conversion functions */
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]) {
char temp[2];
int length = strlen(st);
int i;
char buf = 0;
for(i = 0; i < length; i++) {
if(i % 2 != 0) {
sprintf(temp, "%c", hex_to_ascii(buf, st[i]));
strcat(ret_result, temp);
} else {
buf = st[i];
}
}
}
int hex_to_int(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first*10 + second;
if(result > 9) result--;
return result;
}
int hex_to_ascii(char c, char d) {
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
return high+low;
}
As #ikegami points out in the comments the value passed to key Crypt::CBC is not really a key. This value is passed to another function which combines it with a random salt then hashes it to generate the real key and initialization vector. The random salt is saved with the cypher text the idea being if you encrypt the same data with the same key more than once the output will be different every time.
If you convert your encrypted string to ascii you will notice the first eight characters spell Salted__, this corresponds to the format used by OpenSSL.
See below for a somewhat crude example using OpenSSL's EVP api:
//
// compile with: gcc -o crypt crypt.c -lssl -lcrypto
//
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
int main(int argc, char *argv[]){
char pass[]="fOagmJOKu2SF";
char text[]="53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1";
int i = 0;
char *pos=text;
while(*pos){ // converts hex string to binary in place
sscanf(pos, "%2hhx", &text[i++]);
pos += 2;
} text[i]=0;
EVP_CIPHER_CTX ctx;
unsigned char key[8] = {0};
unsigned char iv[8] = {0};
int len;
char *clear = malloc(strlen(text));
// v-> First Charicter after 'Salted__'
EVP_BytesToKey(EVP_des_cbc(), EVP_md5(), &text[8], pass, strlen(pass), 1, key, iv);
EVP_DecryptInit(&ctx, EVP_des_cbc(), key, iv);
// v-> Cypertext starts after salt
EVP_DecryptUpdate(&ctx, clear, &len, &text[16], strlen(text)-15);
EVP_DecryptFinal(&ctx, clear, &len);
printf("%s\n", clear);
return 0;
}
http://www.ict.griffith.edu.au/anthony/info/crypto/openssl.hints
https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html
This is part of a program where I call a function that reads components from a ".dat" file and save the input to members of a Struct. When I try calling the function from my main.c it gives various errors depending on what I try. Most notably: conflicting types of 'ReadFile' and too few arguments to function 'ReadFile'. I also get a warning "passing argument from 'ReadFile' makes integer from pointer without cast" and some infos.
This is main.c
#include "MyData.h"
#include "NodalA.h"
#include "FileHandling.h"
#include <stdio.h>
#include "windows.h"
int main(){
ComponentType *CircuitData;
int numComp = 6;
int numEl = 0;
int numNodes = 0;
CircuitData = malloc((numComp)*sizeof(ComponentType));
ReadFile(CircuitData, &numEl, &numNodes);
return 0;
}
This is FileHandling.c:
#include "FileHandling.h"
#include "stdio.h"
void ReadFile(ComponentType *CircuitData, int *numEl, int *numNodes){
numEl = 0;
numNodes = 0;
int index = 0;
FILE *data;
data = fopen("mydata.dat", "r");
if (data == NULL){
printf("Error: \"mydata.dat\" could not be opened");
}
else {
while(!feof(data)){
fscanf(data, "%s, %s, %s, %f", CircuitData[index].name, CircuitData[index].node1, CircuitData[index].node2, CircuitData[index].value);
*CircuitData[index].node1 = extractInteger(CircuitData[index].node1);
*CircuitData[index].node2 = extractInteger(CircuitData[index].node2);
if(*CircuitData[index].node1 > *numNodes)
*numNodes = *CircuitData[index].node1;
if(*CircuitData[index].node2 > *numNodes)
*numNodes = *CircuitData[index].node2;
numEl++;
index++;
}
}
fclose(data);
}
And this is MyData.h
#ifndef MYDATA_H_
#define MYDATA_H_
typedef struct Comp{
char name[5]; //Name of circuit component
char node1[5], node2[5]; //2 nodes
float value[5]; //value
}ComponentType;
#endif /* MYDATA_H_ */
Any help would be appreciated. There are more code but I think this is the most important part.
The ReadFile function name used in the program is the same as a ReadFile function in "windows.h". The error "too few arguments to function 'ReadFile'" is most likely caused by the program trying to call the the function from windows with the wrong arguments. Removing "windows.h" or renaming the function ReadFile to something else solves the problem.