I can't seem to wrap my head around this concept of reading in 64byte chunks, then using the blowfish,
BF_cfb64_encrypt(source, dest, sizeof(source), &bf_key, iv, &enc, BF_DECRYPT)
function to encrypt? it. I know how to use the BF function, but reading in 64 bytes, from say a 4096 byte file is my confusion. Any tips or suggestions would be greatly appreciated. My understanding is that 1 char is a byte, so does that mean I simply keep a count and when char count is 8 then that means I have read 64 bytes, hence encrypt, then write to file, and repeat until the entire file is parsed?
First, familiarity with your stream cipher is probably warranted. Blowfish encrypts/decrypts using a block size of 64 bits; not bytes. So long as you understand the 64 "bytes" you're referring to is your requirement and not Blowfishes, and that Blowfish only requires 8-byte blocks.
That said, a loop passing over a file with a size that is a multiple of the algorithm block size, extracting decrypted data one 64 byte frame at a time is certainly doable.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <openssl/blowfish.h>
int main(int argc, char *argv[])
{
if (argc < 2)
return EXIT_FAILURE;
FILE * fp = fopen(argv[1], "rb");
if (fp == NULL)
{
perror(argv[1]);
return EXIT_FAILURE;
}
// your key bytes would be here (obviously).
unsigned char key[16] = "1234567890123456";
int key_len = sizeof(key)-1;
// setup the key schedule.
BF_KEY bf_key;
BF_set_key(&bf_key, key_len, key);
// and setup the initialization vector. normally the IV is
// randomly generated when encrypting, then stored as the
// lead 8 bytes of ciphertext output. this assumes you're
// iv is static (all zeros) similar to SSH
unsigned char iv[8] = {0};
int n = 0;
// finally, begin reading the data in chunks of 64 bytes
// sending it through the blowfish algorithm
unsigned char source[64];
unsigned char dest[64];
while (fread(source, sizeof(source), 1, fp) == 1)
{
BF_cfb64_encrypt(source, dest, sizeof(dest), &bf_key, iv, &n, BF_DECRYPT);
// do something with your dest[] plaintext block
}
fclose(fp);
return 0;
}
That sample is fairly trivial, but it brings up some things about symmetric block algorithms and padding that you may not be considering (or perhaps you have, and it simply has nothing to do with this question).
Symmetric block algorithms like Blowfish operate on a block size. In the case of Blowfish that block size is 64 bits (8 bytes). This means that the encryption/decryption operation always happens in 64-bit-sized chunks. If if you were using the lower level openssl apis you would have to encrypt (and decrypt) the data in blocks no larger than that. The higher-level APIs (such as BF_cfb64_encrypt) are designed to allow "stream mode" meaning you can submit your data in larger chunks, so long as they're sized to be a multiple of the block size. and you retain the iv and n values between chained successive calls to the API.
Finally, I started writing this rather long diatribe about symmetric block algorithms and padding modes, but realized this isn't really appropriate to this question, so I can only suggest you research into them. I've a suspicion you'll need to at some point.
Why donot you use read system call?
Required Include Files
#include <unistd.h>
Function Definition
size_t read(int fildes, void *buf, size_t nbytes);
Parameters
int fildes : The file descriptor of where to read the input. You can either use a file descriptor obtained from the open system call, or you can use 0, 1, or 2, to refer to standard input, standard output, or standard error, respectively.
const void *buf : A character array where the read content will be stored.
size_t nbytes : The number of bytes to read before truncating the data. If the data to be read is smaller than nbytes, all data is saved in the buffer.
return value : Returns the number of bytes that were read. If value is negative, then the system call returned an error.
Sample
#include <unistd.h>
int main()
{
char data[128];
if(read(0, data, 128) < 0)
write(2, "An error occurred in the read.\n", 31);
exit(0);
}
** Pseudo Code **
int no_byte_read = 0; // Will store number of byte read
void *buffer; //temporary storage for read data
FILE *fp; //File pointer of the file to be read
buffer = (void*) malloc(64); //Allocate space to temporary buffer.
fp = open file to be read;
do{
no_byte_read = read(fp, buffer, 64); // read 64 byte from file and store in buffer
if(no_byte_read < 0){
printf("Error occoured in read");
break;
}
}while(no_byte_read == 64) //If this condition is true that means still some bytes
remain in file which must be read.
Related
I recently started dabbing in C again, a language I'm not particularly proficient at and, in fact, keep forgetting (I mostly code in Python). My idea here is to read data from a hypothetically large file as chunks and then process the data accordingly. For now, I'm simulating this by actually loading the whole file into a buffer of type short with fread. This method will be changed, since it would be a very bad idea for, say, a file that's 1 GB, I'd think. The end goal is to read a chunk as one, process, move the cursor, read another chunk and so on.
The file in question is 43 bytes and has the phrase "The quick brown fox jumps over the lazy dog". This size is convenient because it's a prime number, so no matter how many bytes I split it into, there will always be trailing garbage (due to the buffer having leftover space?). Data processing in this case is just printing out the shorts as two chars after byte manipulation (see code below)
#include <stdio.h>
#include <stdlib.h>
#define MAX_BUFF_SIZE 1024
long file_size(FILE *f)
{
if (fseek(f, 0, SEEK_END) != 0) exit(EXIT_FAILURE); // Move cursor to the end
long file_size = ftell(f); // Determine position to get file size
rewind(f);
return file_size;
}
int main(int argc, char* argv[])
{
short buff[MAX_BUFF_SIZE] = {0}; // Initialize to 0 remove trailing garbage
char* filename = argv[1];
FILE* fp = fopen(filename, "r");
if (fp)
{
size_t size = sizeof(buff[0]); // Size in bytes of each chunk. Fixed to 2 bytes
int nmemb = (file_size(fp) + size - 1) / size; // Number of chunks to read from file
// (ceil f_size/size)
printf("Should read at most %d chunks\n", nmemb);
short mask = 0xFF; // Mask to take first or second byte
size_t num_read = fread(buff, size, nmemb, fp);
printf("Read %lu chunks\n\n", num_read); // Seems to have read more? Look into.
for (int i=0; i<nmemb; i++) {
char first_byte = buff[i] & mask;
char second_byte = (buff[i] >> 8) & mask; // Identity for 2 bytes. Keep mask for consistency
printf("Chunk %02d: 0x%04x | %c %c\n", // Remember little endian (bytes reversed)
i, buff[i], first_byte, second_byte);
}
fclose(fp);
} else
{
printf("File %s not found\n", filename);
return 1;
}
return 0;
}
Now yesterday, on printing out the last chunk of data I was getting "Chunk 21: 0xffff9567 | g". The last (first?) byte (0x67) is g, and I did expect some trailing garbage, but I don't understand why it was printing out so many bytes when the variable buff has shorts in it. At that point I was just printing the hex as %x, not %04x, and buff was not initialized to 0. Today, I decided to initialize it to 0 and not only did the garbage disappear, but I can't recreate the problem even after leaving buff uninitialized again.
So here are my questions that hopefully aren't too abstract:
Does fread look beyond the file when reading data and does it remove trailing garbage itself, or is it up to us?
Why was printf showing an int when the buffer is a short? (I assume %x is for ints) and why can't I replicate the behaviour even after leaving buff without initialization?
Should I always initialize the buffer to zero to remove trailing garbage? What's the usual approach here?
I hope these aren't too many, or too vague, questions, and that I was clear enough. Like I said, I don't know much about C but find low-mid level programming very interesting, especially when it comes to direct data bit/byte manipulation.
Hope you have a great day!
EDIT 1:
Some of you wisely suggested I use num_read instead of nmemb on the loop, since that's the return value of fread, but that means I'll discard the rest of the file (nmemb is 22 but num_read is 21). Is that the usual approach? Also, thank you for pointing out that %x was casting to unsigned int, hence the 4 bytes instead of 2.
EDIT 2:
For clarification, and since I mispoke in a comment, I'd like to keep the remaining byte (or data), while discarding the rest, which is undefined. I don't know if this is the usual approach since if I use num_read in the loop, whatever is leftover at the end is discarded, data or not. I'm more interested in knowing what the usual approach is: discard leftover data or remove anything that we know is undefined, in this case one of the bytes.
I need to be able to make sure my array is correctly receiving values from the file card.raw through fread.
I am not confident about using arrays with pointers, so if anybody could help me with the theory here, it would be GREATLY appreciate it. Thanks in advance.
The code is supposed to take literally one block of size 512 bytes and stick it into the array. Then I am just using a debugger and printf to examine the arrays output.
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char* argv[])
{
//Size of EACH FAT JPEG in bytes
#define FILESIZE 512
unsigned char* buffer[FILESIZE];
///Step 1: Open jpeg
FILE* readfrom = fopen("card.raw", "rb");
if (readfrom == NULL)
{
printf("Could not open");
}
///Step 2: Find Beginning of JPEG. The first digits will be 255216255 Then 224 or 225
fread(&buffer, FILESIZE, 1, readfrom);
for(int x = 0; x < FILESIZE; x++)
{
printf("%d = %c\n", x, buffer[x]);
}
fclose(readfrom);
}
Use return values from input functions. fread() reports how many elements were read - code might not have read 512. Swap FILESIZE, 1 to detect the number of characters/bytes read.
// fread(&buffer, FILESIZE, 1, readfrom);
size_t count = fread(&buffer, 1, FILESIZE, readfrom);
Only print out up to the number of elements read. Recommend hexadecimal (and maybe decimal) output rather than character.
for(size_t x = 0; x < count; x++) {
// printf("%d = %c\n", x, buffer[x]);
printf("%3zu = %02X % 3u\n", x, buffer[x], buffer[x]);
}
If the fopen() failed, best to not continue with for() and fclose().
if (readfrom == NULL) {
printf("Could not open");
return -1;
}
The second parameter is size, in bytes, of each element to be read.
The third parameter is Number of elements each one with a size of the <second parameter> bytes.
So, swap your second and first parameters.
Replace unsigned char* buffer[FILESIZE]; with unsigned char buffer[FILESIZE];. For now, you have an array of unsigned char *, when you need unsigned char. Because buffer is already a pointer, you don't need to take its address. In fread call, replace &buffer with buffer.
It must go like this: fread(buffer, 1, FILESIZE, readfrom);
One more thing: add return with a specific error code after printf("Could not open");, because if file hasn't been open, you cannot read from it, can you? And add return 0; in the end of main.
And take your #define out of main.
Read more about fread here: http://www.cplusplus.com/reference/cstdio/fread/
Here i am using two different functions for calculating CRC16 for any type of file (.txt,.tar,.tar.gz,.bin,.scr,.sh etc) and different size also varies from 1 KB to 5 GB.
I want to achieve this
`cross platform
less time consuming
Have to work proper for any type of file and any size`
i got same value of CRC in both functions. but any one can tell me which one is more better to calculate CRC16 for any type of file with any size on different different platform.
Here we have to consider 0 to 255 all type characters.
Can any body please suggest me which one is good in my requirements.
Code of both functions :
First one which has int datatype in readChar here i am using int readChar
int CRC16_int(const char* filePath) {
//Declare variable to store CRC result.
unsigned short result;
//Declare loop variables.
int intInnerLoopIndex;
result = 0xffff; //initialize result variable to perform CRC checksum calculation.
//Store message which read from file.
//char content[2000000];
//Create file pointer to open and read file.
FILE *readFile;
//Use to read character from file.
int readChar;
//open a file for Reading
readFile = fopen(filePath, "rb");
//Checking file is able to open or exists.
if (!readFile) {
fputs("Unable to open file %s", stderr);
}
/*
Here reading file and store into variable.
*/
int chCnt = 0;
while ((readChar = getc(readFile)) != EOF) {
//printf("charcater is %c\n",readChar);
//printf("charcater is %c and int is %d \n",readChar,readChar);
result ^= (short) (readChar);
for (intInnerLoopIndex = 0; intInnerLoopIndex < 8; intInnerLoopIndex++) {
if ((result & 0x0001) == 0x0001) {
result = result >> 1; //Perform bit shifting.
result = result ^ 0xa001; //Perform XOR operation on result.
} else {
result = result >> 1; //Perform bit shifting.
}
}
//content[chCnt] = readChar;
chCnt++;
}
printf("\nCRC data length in file: %d", chCnt);
//This is final CRC value for provided message.
return (result);
}
Second one is unsigned char datatype of readChar Here i am using unsigned char readChar
int CRC16_unchar(const char* filePath) {
unsigned int filesize;
//Declare variable to store CRC result.
unsigned short result;
//Declare loop variables.
unsigned int intOuterLoopIndex, intInnerLoopIndex;
result = 0xffff; //initialize result variable to perform CRC checksum calculation.
FILE *readFile;
//Use to read character from file.
//The problem is if you read a byte from a file with the hex value (for example) 0xfe,
//then the char value will be -2 while the unsigned char value will be 254.
//This will significantly affect your CRC
unsigned char readChar;
//open a file for Reading
readFile = fopen(filePath, "rb");
//Checking file is able to open or exists.
if (!readFile) {
fputs("Unable to open file %s", stderr);
}
fseek(readFile, 0, SEEK_END); // seek to end of file
filesize = ftell(readFile); // get current file pointer
fseek(readFile, 0, SEEK_SET); // seek back to beginning of file
/*
Here reading file and store into variable.
*/
int chCnt = 0;
for (intOuterLoopIndex = 0; intOuterLoopIndex < filesize; intOuterLoopIndex++) {
readChar = getc(readFile);
printf("charcater is %c and int is %d\n",readChar,readChar);
result ^= (short) (readChar);
for (intInnerLoopIndex = 0; intInnerLoopIndex < 8; intInnerLoopIndex++) {
if ((result & 0x0001) == 0x0001) {
result = result >> 1; //Perform bit shifting.
result = result ^ 0xa001; //Perform XOR operation on
} else {
result = result >> 1; //Perform bit shifting.
}
}
chCnt++;
}
printf("\nCRC data length in file: %d", chCnt);
return (result);
}
Please Help me to figure out this problem
Thanks
First things first. Don't do file reading (or whatever the source is) and CRC calculating in the same function. This is bad design. File reading is typically not completely platform independent (although POSIX is your best friend), but CRC calculation can be done very platform independently. Also you might want to reuse your CRC algorithm for other kind of data sources which aren't accessed with fopen().
To give you a hint, the CRC function I always drop in to my projects has this prototype:
uint16_t Crc16(const uint8_t* buffer, size_t size,
uint16_t polynomial, uint16_t crc);
You don't have to call the function once and feed it the complete contents of the file. Instead you can loop through the file in blocks and call the function for each block. The polynomial argument in your case is 0xA001 (which is BTW a polynomial in 'reversed' form), and the crc argument is set to 0xFFFF the first time. Each subsequent time you call the function you pass the previous return value of the function to the crc argument.
In your second code frament (CRC16_unchar) you first determine the filesize and then read that number of bytes. Don't do that, it unnecessary limits you to handle files of maximum 4GB (in the most cases). Just reading until EOF is cleaner IMHO.
Furthermore I see that you are struggling with signed/unsigned bytes. Do know that
printf doesn't know if you pass an signed or unsigned integer. You tell printf with '%d' or '%u' how to interpret the integer.
Even in C itself there is hardly a difference between a signed and unsigned integer. C won't magically change the value of 255 to -1 if you do int8_t x = 255.
See this anser for more details about when C uses the signedness of an integer: When does the signedness of an integer really matter?. Rule of thumb: Just always use uint8_t for handling raw bytes.
So both functions are fine regarding signedness/integer size.
EDIT: As other users indicated in their answers, read the file in block instead per-byte:
uint16_t CRC16_int(const char* filePath) {
FILE *readFile;
const uint8_t buf[1024];
size_t len;
uint16_t result = 0xffff;;
/* Open a file for reading. */
readFile = fopen(filePath, "rb");
if (readFile == NULL) {
exit(1);
}
/* Read until EOF. */
while ( (len = fread(buf, sizeof(buf), 1, readFile)) > 0 ) {
result = Crc16(buf, len, 0xA001, result);
}
/* readFile could be in error state, check it with ferror() or feof() functions. */
return result;
}
Also you should alter you function prototype to make it possible to return an error, e.g.:
// Return true when successful, false on error. CRC is stored in result.
bool CRC16_int(const char* filePath, uint16_t *result)
You want to read and write 8-bit bytes using unsigned char instead of plain char because char can be either signed or unsigned and that's up to the compiler (allowed by the C standard). So, the value you get from getc() should be converted to unsigned char prior to being used in the CRC calculations. You could also fread() into an unsigned char. If you work with signed chars, sign extension of chars into ints will likely break your CRC calculations.
Also, per the C standard fseek(FilePtr, 0, SEEK_END) has undefined behavior for binary streams and binary streams need not meaningfully support SEEK_END in fseek(). In practice, though, this usually works as we want.
Another thing you should consider is checking for I/O errors. Your code is broken in this respect.
The datatype you do the calculation with should, in my opinion, not be the same that you read from the file. Doing one function call into the runtime library to read a single byte is simply not efficient. You should probably read on the order of 2-4 KB at a time, and then iterate over each returned "chunk" in whatever manner you choose.
There's also absolutely no point in reading in the size of the file in advance, you should simply read until reading returns less data than expected, in which case you can inspect feof() and ferror() to figure out what to do, typically just stop since you're done. See the fread() manual page.
The goal:
Open a file with binary data, read the whole file into memory, change some parts oft he file, write the memory buffer to the file, close the file. Profit?
The problem:
I have just started learning C and I can't find enough information about how to change to binary data in the memory buffer. Coming from a web developer background (php, python, as3) this is new territory for me.
The context:
I have a function which takes the path to the file and a pointer adress to a char pointer memory buffer. It then opens the file, loops through the file and writes data to the memory buffer. Finally closes the file.
The purpose of the binary file is to hold category-ids for some objects and their position is their own id. The category-ids are represented as 2 byte shorts. So essentially it's just a binary file filled with lots of shorts that I want to be able to read and change.
Here's what I got so far:
main.c:
#include "binary-handler.h"
void showFileBuffer(char *buffer, unsigned int fileSize){
int i = 0;
for(; i < fileSize; ++i){
printf("<%d:%x>\n", i, ((char *)buffer)[i]);
}
}
int main(){
char path[] = "assets/map-squares.bin";
char *buffer;
int fileSize;
fileSize = readFileToMemory(path, &buffer);
showFileBuffer(buffer, fileSize);
//Code to change buffer
//Code to write buffer to file
return 0;
}
binary-handler.c:
#include <stdio.h>
#include <stdlib.h>
unsigned int getFileSize(FILE **file){
unsigned int size;
if(fseek(*file, 0, SEEK_END) == -1){ return -1; }
size = ftell(*file);
fseek(*file, 0, SEEK_SET);
return size;
}
char *getFileBuffer(FILE **file, unsigned int fileSize){
char *buffer = malloc(fileSize + 1);
fread(buffer, fileSize, 1, *file);
return buffer;
}
unsigned int readFileToMemory(char path[], char **buffer){
unsigned int fileSize;
FILE *file = fopen(path, "rb");
if(file != NULL){
fileSize = getFileSize(&file);
*buffer = getFileBuffer(&file, fileSize);
fclose(file);
return fileSize;
}else{
*buffer = NULL;
return -1;
}
}
1. Will this code produce the first step (reading file to memory) correctly?
2. If yes, how can I change, say the 2nd object in the buffer to have a value of 0F 00?
3. How can I take the buffer and write it back to the file?
4. Is there a way for me to check the values in the buffer in a verbose way?
All in all I just want help with getting a grasp of the whole concept so I can solve this myself.
Thanks!
Edit: Removed the looping of the file. Added a function which prints the whole buffer.
1) No. You do not need to loop in getFileBuffer since you read the entire file with fread. You also do not need to call fseek because every time you read from the file you will advance within the file stream automatically. I haven't debugged your code, but it looks like by the time your loop completes, every element in buffer will contain the same value and it will be equal to whatever is the last byte in your file.
Note: The arguments your specified for fread are backwards. The second parameter is the size of the type you are reading which should be sizeof(char). The third parameter should be the amount of chars you want to read which should be fileSize. Your code still works, though, but it is saying it wants to read 1 object that is fileSize bytes long when you are reading fileSize objects that are 1 byte long.
2) You can read the second short value like this (in little endian):
short n = 0;
n |= buffer[2] << 0;
n |= buffer[3] << 8;
You can write the short back to the file like this:
buffer[2] = n >> 0;
buffer[3] = n >> 8;
3) fwrite
4) I don't understand what you are asking.
I wish to open a binary file, to read the first byte of the file and finally to print the hex value (in string format) to stdout (ie, if the first byte is 03 hex, I wish to print out 0x03 for example). The output I get does not correspond with what I know to be in my sample binary, so I am wondering if someone can help with this.
Here is the code:
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char* argv[])
{
int fd;
char raw_buf[1],str_buf[1];
fd = open(argv[1],O_RDONLY|O_BINARY);
/* Position at beginning */
lseek(fd,0,SEEK_SET);
/* Read one byte */
read(fd,raw_buf,1);
/* Convert to string format */
sprintf(str_buf,"0x%x",raw_buf);
printf("str_buf= <%s>\n",str_buf);
close (fd);
return 0;
}
The program is compiled as follows:
gcc rd_byte.c -o rd_byte
and run as follows:
rd_byte BINFILE.bin
Knowing that the sample binary file used has 03 as its first byte, I get the output:
str_buf= <0x22cce3>
What I expect is
str_buf= <0x03>
Where is the error in my code?
Thank you for any help.
You're printing the value of the pointer raw_buf, not the memory at that location:
sprintf(str_buf,"0x%x",raw_buf[0]);
As Andreas said, str_buf is also not big enough. But: no need for a second buffer, you could just call printf directly.
printf("0x%x",raw_buf[0]);
Less is more...
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
int fd;
unsigned char c;
/* needs error checking */
fd = open(argv[1], O_RDONLY);
read(fd, &c, sizeof(c));
close(fd);
printf("<0x%x>\n", c);
return 0;
}
seeking is not needed
if you want to read a byte use an unsigned char
printf will do the format
I think that you are overcomplicating things and using non-portable constructs where they aren't really necessary.
You should be able to just do:
#include <stdio.h>
int main(int argc, char** argv)
{
if (argc < 2)
return 1; /* TODO: better error handling */
FILE* f = fopen(argv[1], "rb");
/* TODO: check f is not NULL */
/* Read one byte */
int first = fgetc(f);
if (first != EOF)
printf("first byte = %x\n", (unsigned)first);
/* TODO else read failed, empty file?? */
fclose(f);
return 0;
}
str_buf has a maximum size of 1 (char str_buf[1];), it should at least 5 bytes long (4 for XxXX plus the \0).
Moreover, change
sprintf(str_buf,"0x%x",raw_buf);
to
sprintf(str_buf,"0x%x",*raw_buf);
otherwise you'll print the address of the raw_buf pointer, instead of its value (that you obtain by dereferencing the pointer).
Finally, make sure both raw_buf is unsigned. The standard specified that the signness of chars (where not explicitly specified) is implementation defined, ie, every implementation decides whether they should be signed or not. In practice, on most implementations they are signed by default unless you're compiling with a particular flag. When dealing with bytes always make sure they are unsigned; otherwise you'll get surprising results should you want to convert them to integers.
Using the information from the various responses above (thank you all!) I would like to post this piece of code which is a trimmed down version of what I finally used.
There is however a difference between what the following code does and what was described in my origal question : this code does not read the first byte of the binary file header as described originally, but instead reads the 11th and 12th bytes (offsets 10 & 11) of the input binary file (a .DBF file). The 11th and 12th bytes contain the length of a data record (this is what I want to know in fact) with the Least Significant Byte positioned first: for example, if the 11th and 12th bytes are respectivly : 0x06 0x08, then the length of a data record would be 0x0806 bytes, or 2054bytes in decimal
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char* argv[]) {
int fd, dec;
unsigned char c[1];
unsigned char hex_buf[6];
/* No error checking, etc. done here for brevity */
/* Open the file given as the input argument */
fd = open(argv[1], O_RDONLY);
/* Position ourselves on the 11th byte aka offset 10 of the input file */
lseek(fd,10,SEEK_SET);
/* read 2 bytes into memory location c */
read(fd, &c, 2*sizeof(c));
/* write the data at c to the buffer hex_buf in the required (reverse) byte order + formatted */
sprintf(hex_buf,"%.2x%.2x",c[1],c[0]);
printf("Hexadecimal value:<0x%s>\n", hex_buf);
/* copy the hex data in hex_buf to memory location dec, formatting it into decimal */
sscanf(hex_buf, "%x", &dec);
printf("Answer: Size of a data record=<%u>\n", dec);
return 0;
}