principle
- Remove invalid characters "0x", "\n", spaces, etc., starting from the first valid character (ie 0~F), and output a formatted HEX byte for every 2 valid characters that meet the conversion conditions.
- After the character string is input, every two characters are converted into a byte (Hex), such as: 9F01 saves four bytes in ASCII code, and outputs two bytes in a hexadecimal file: 9F01
How to use
Set the absolute path (path + file name) of input/output, such as:
日志| please set source file path:
输入| D:/test/input.txt
日志| please set output file path:
输入| D:/test/output.txt
program
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS
#define PAYLOAD_OFFSET 0
#define INVALID_CHARACTOR 0x10 //valid:0x0~0xF
unsigned char HexChar(unsigned char c);
char* getFilePath(void);
int find_next_number(unsigned char* pbData, int size);
int main(void)
{
size_t result = -1;
FILE* pFile = NULL;
unsigned char* pbFileData = NULL;
unsigned char* pbHexData = NULL;
int dFileSize = 0;
char* pbSourcePath = NULL;
char* pbOutput = NULL;
printf("please set source file path: \n");
pbSourcePath = getFilePath();
printf("please set output file path: \n");
pbOutput = getFilePath();
if (!pbSourcePath || !pbOutput) {
printf("[error] invalid path of %s.\n", (!pbSourcePath ? "source file" : "ouput file"));
return -1;
}
pFile = (FILE*)fopen(pbSourcePath, "rb");
if (!pFile) {
printf("[error] failed to open file: %s.\n", pbSourcePath);
return -1;
}
fseek(pFile, 0L, SEEK_END);
dFileSize = ftell(pFile);
rewind(pFile);
pbFileData = (unsigned char*)malloc(dFileSize);
pbHexData = (unsigned char*)malloc(dFileSize / 2);
if (!pbFileData || !pbHexData) {
printf("[error] failed to alloc memory.\n");
return -1;
}
memset(pbFileData, 0x00, dFileSize);
memset(pbHexData, 0x00, dFileSize / 2);
printf("source file size: %d.\n", dFileSize - PAYLOAD_OFFSET);
result = fread(pbFileData, dFileSize, 1, pFile);
if (1 != result)
{
fputs("reading error", stderr);
printf("[error] failed to read file: %s\n", pbSourcePath);
free(pbFileData);
pbFileData = NULL;
return -1;
}
int i = 0;
int j = PAYLOAD_OFFSET;
j += find_next_number(&pbFileData[j], dFileSize - j);
for (; j + 1 < dFileSize; j += 2 + find_next_number(&pbFileData[j + 2], dFileSize - j - 2))
{
if (INVALID_CHARACTOR != HexChar(pbFileData[j + 1]))
pbHexData[i++] = (HexChar(pbFileData[j]) << 4) + HexChar(pbFileData[j + 1]);
else
printf("[error] ignore a half-byte '%c%c', offset = %d\n", pbFileData[j], pbFileData[j + 1], j);
}
i--;
fclose(pFile);
FILE* fp = fopen(pbOutput, "wb");
if (fp == NULL) {
printf("[error] failed to open file: %s.\n", pbOutput);
return -1;
}
fwrite(pbHexData, 1, i, fp);
fclose(fp);
printf("translation complete, file size: %d.\n", i);
return 0;
}
int find_next_number(unsigned char* pbData, int size)
{
int i = 0;
for (; i < size && INVALID_CHARACTOR == HexChar(pbData[i]); i++)
;
return i;
}
char* getFilePath(void)
{
#define PATH_MAX_LEN 512
char* p = NULL;
int i = 0;
p = (char*)malloc(PATH_MAX_LEN);
if (!p)
return NULL;
for (i = 0; i < PATH_MAX_LEN; i++)
{
scanf("%c", &p[i]);
if ('\n' == p[i])
break;
}
if (i < PATH_MAX_LEN) {
p[i] = 0;
}
else {
printf("file path too long.\n");
free(p);
return NULL;
}
return p;
}
unsigned char HexChar(unsigned char c)
{
if ((c >= '0') && (c <= '9'))
return c - 0x30;
else if ((c >= 'A') && (c <= 'F'))
return c - 'A' + 10;
else if ((c >= 'a') && (c <= 'f'))
return c - 'a' + 10;
return INVALID_CHARACTOR;
}