/**
** You DO NOT want to do this usually...
**/
#include <stdint.h>
uint_fast64_t
concatIPv4Addr(uint_fast16_t parts[])
{
uint_fast64_t n = 0;
for (int i = 0; i < 3; ++i) {
n += parts[i];
n *= 1000;
}
return (n += parts[3]);
}
I used the "fast" integer types for speed purposes, but if you have a storage requirement, use the corresponding "least" types instead. Of course this assumes you have a C99 compiler or a C89 compiler with extensions. Otherwise you're stuck with the primitive types where a char
could even be 32-bit according to the C standard. Since I don't know your target environment, I made no assumptions. Feel free to change to the appropriate primitive types as you see fit.
I used a 16-bit value (minimum) because an 8-bit number can only represent 0-255, meaning if 358 was entered accidentally, it would be interpreted as 102, which is still valid. If you have a type able to store more than 8 bits and less than 16 bits, you can obviously use that, but the type must be able to store more than 8 bits.
That aside, you will need at least a 38-bit type:
4294967295 (32-bit unsigned max)
255255255255 (255.255.255.255 converted to the integer you want)
274877906944 (38-bit unsigned max)
The function above will convert 127.0.1.1 and 127.0.0.11 to 127000001001 and 127000000011 respectively:
127.0.1.1 ->
127.000.001.001 ->
127000001001
127.0.0.11 ->
127.000.000.011 ->
127000000011
Why so many zeros? Because otherwise you can't tell the difference between them! As others have said, you could confuse 127.0.1.1 and 127.0.0.11. Using the function above or something more appropriate that actually converts an IPv4 address to its real decimal representation, you won't have such a problem.
Lastly, I did no validation on the IPv4 address passed to the function. I assume you already ensure the address is valid before calling any functions that save or use the IPv4 address. BTW, if you wanted to do this same thing for IPv6, you can't so easily because that would require a string or conversion to decimal of each of the 8 parts, each of which is at most 16-bit, yielding 5 decimal digits per part, or 40 digits. To store that, you'd need a minimum of 133 bits, rather than the 128 bits required for the IPv6 address, just as you'd need 38 bits to store an IPv4 address instead of the 32 bits required.
Still not too bad, right? How about a theoretical IPv8 where there are 16 parts, each of which are 32-bit in size? The equivalent function to the one above would require 580 bits, instead of the proper mathematical requirement: 512 bits. While not a problem today, I'm simply pointing out the error in doing anything with an IPv4 address represented by concatenating the decimal values of each part. It scales absolutely terribly.