-1

I have this data file in hexadecimal and I want to convert them to big endian from little endian but I come across this trouble in C++. C++ treats 2 hexa value as one to make a byte for char and always outputs decimal equivalent to those 2 combined hexa value but I don't want this.

Say I am reading a date, 8 byte in little endian:

e218 70d2 0e00 0000

Code:

char buffer;
for(int i = 0; i<BYTE_SIZE; ++i){
    infile>>buffer;
    cout<<"Read In Int = "<<(unsigned int)buffer<<endl;
    cout<<"Read as Hex= "<<hex<<(int)buffer<<endl;


}

Output:

Read as Int= 226

Read as Hex= e2
-------------End of First Iter-------------------------
Read as Int= 18

Read as Hex= 18
...

So if you note that e2, which is in base 16, is concatenated as one entity. When you convert to int, you get: 14*16 + 2 = 226. I want to read e only and then 2 only and so on.... My main goal is to flip it and read it as 18e2 and convert that to decimal. How can I do this?

Update: I think people are misunderstanding this question. I simply wanted a way to read binary file containing hexa values and shift things around individually. This problem was hard to describe on text but anyway, Thank you to those who commented with possible solutions.

Sadij
  • 51
  • 8
  • What do you mean by "e2 is concatenated as one and converted to 226"? It's very unclear to me what the file actually contains, or what you expect the result to be. To make things very simple to start with: what is the first byte in your file, and what do you expect to happen to it? – Jon Skeet Apr 29 '18 at 15:21
  • @DaisyShipton **e2** is in base 16 hexa value. Like e = 14,... So, when reading it from a file, e2 is treated as one entity and converted as following: 14*16 + 2 = 226....Say, the first byte in my file is **e2**. – Sadij Apr 29 '18 at 15:25
  • 2
    "Say, the first byte in my file is e2" - Right, so it's not that your file is "in hexadecimal", it's just a binary file. Hexadecimal is simply a textual way of representing numbers. It would be reasonable to talk about a file as "containing hex content" if it's actually a *text* file, e.g. with text of "e2 ab" etc. But otherwise, it's just bytes. So, now that we know you've got a binary file, what are you expecting to happen? Currently you're reading a single byte - and that looks correct to me. What were you expecting? – Jon Skeet Apr 29 '18 at 15:29
  • "data file in hexadecimal " - what you have shown in your question is a _text_ file containing 4 hex-digit values, but it is not clear if there are white space delimiters. Have you done / could you show a hexdump of your input file to clarify? "The hexdump utility is a filter which displays the specified files in a user specified format." (show the command you used, and limit the bytes) – 2785528 Apr 29 '18 at 15:36
  • @DaisyShipton ahh I see. It is in fact binary file. I mustve confused myself...So, I am reading and storing them into character buffer where it is storing 1 byte at a time but ,ultimately,I wanna convert them into **18e2** and then get decimal equivalent.... Im trying my best to explain but its really hard to put it on text. – Sadij Apr 29 '18 at 15:41
  • 1
    Binary files are streamed in using a read function such as "ifstream::read()". This "Behaves as UnformattedInputFunction." The overloaded operator '>>' is for formatted i/o, not binary i/o. – 2785528 Apr 29 '18 at 15:44
  • @DOUGLASO.MOEN this is the original data. This is date, 8 byte in little endian. I want this to be in big endian and convert it to decimal equivalent. e218 70d2 0e00 0000 – Sadij Apr 29 '18 at 15:45
  • https://stackoverflow.com/questions/3823921/convert-big-endian-to-little-endian-when-reading-from-a-binary-file – Sneftel Apr 29 '18 at 15:50
  • 1
    So it sounds like you should read two bytes, multiply the second value by 256 and add the first value - so if you read 0xe2 and than 0x18, you should get an answer of 6370 (decimal). There may well be a way of doing that directly in a single step in C++, but I'm not a C++ dev :( – Jon Skeet Apr 29 '18 at 15:50
  • 1
    @Sadij your platform is likely little endian , right? if so, you should look for little-endian to big endian conversion (POSIX even got functions defined for that). and you may read int64_t straight away before that. But you should use raw streaming because >> operator swallows/converts special characters – Swift - Friday Pie Apr 29 '18 at 16:19
  • 1
    There are also network functions to fix endianess - see "man htonl" (or htons, or ntohl, or ntohs) - these are used to convert values between host and network byte order. i.e. If your host is same as network, these do nothing. But you need to confirm the size of the data fetched out of the stream ... are they all the same? or is some some sort of struct overlay on the data? – 2785528 Apr 29 '18 at 19:11
  • 1
    " ...I simply want a way to read binary file containing hexa values" - if you are reading binary data, the values have no text format info. A "hex value" is a text description of a binary data. There is no text in a binary file. You must use some form of stream::read() to bring in to your program, as only read will ignore the randomly placed line-feed, tab, or other control characters that make text files possible, and that a binary file might have in any order. – 2785528 Apr 29 '18 at 19:19
  • 1
    I started writing a MCVE to describe / demonstrate how the binary file might have been created. (so you might find ideas how to retrieve it). It would appear to me you know how the rest of the binary data stream is organized. Clearly you don't want to share. Anyway, the related research term might be 'persistent data'. There are several existing packages that support this and the idea of 'serialize data'. Good luck. – 2785528 Apr 29 '18 at 22:08

1 Answers1

-2

Played with bits and solved it using:

Preprocessing:

vector<bitset<64>> input;
for(int i = 0; i<SIZE; ++i){
    infile>>buffer;
    input.push_back(bitset<64>(buffer));


}

Here is the function:

unsigned long convert(vector<bitset<64>> input)
{
    bitset<64> data ;
    for(int i = input.size()-1; i>-1; --i)
        data=data|(input[i]<<i*8);
    return data.to_ullong();
}
Sadij
  • 51
  • 8
  • So, this suggests every input is 8 bytes long? This contradicts other info you have provided ... "My main goal is to flip it and read it as 18e2 and convert that to decimal." 18e2 is only 2 bytes, unless it has 6 bytes of 0's preceding it, which you did not mention. – 2785528 Apr 29 '18 at 19:22
  • @DOUGLASO.MOEN You are correct! For simplicity, I only asked for ideas for 2 bytes. Originally for my data, I needed to flip 8 bytes. My data might have critical information so therefore I avoided posting everything here..... I am very new to networking so don't know a lot of functions and was writing everything from scratch which may be the reason why I was struggling. – Sadij Apr 30 '18 at 17:45
  • 1
    Researc ideas 'persistent data' and 'existing packages that support serialize data' – 2785528 Apr 30 '18 at 20:12