Thread: Converting 32 bit binary IP to decimal IP (vice-versa)

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    23

    Converting 32 bit binary IP to decimal IP (vice-versa)

    Hello,

    I am new to this site and the program language of C.

    I am trying to create a program that would allow me to convert 32 bit binary (in chunks of 8 bits) ip to decimal ip. Also, I am trying to convert from decimal ip to 32 bit binary ip.

    I am totally lost to convert 32 bit binary to decimal ip but I think I have an understanding of converting decimal ip to 32 bit binary ip.

    Any help would be greatly appreciated.

    Here is the code I have so far for decimal IP to Binary IP (Am I missing anything?)
    Code:
    {
    // Initialize the variables
    unsigned long a,b,c,d,base10IP;
    
    // Get the IP address from user
    cout << "\nEnter an IP address in dotted quad notation (x.x.x.x)";
    cout << "\nwith each section seperated by a space: ";
    cin >> a >> b >> c >> d;
    
    // Do calculations to covert IP to base 10
    a *= 16777216;
    b *= 65536;
    c *= 256;
    base10IP = a + b + c + d;
    
    // Output new IP address
    cout << "\nThe converted address is: " << base10IP << '\n';
    }

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I was of the impression that there were already macros to handle these things. why not do it like this:

    Code:
    union ip
    {
      int ip32;
      char ip8x4[4];
    };

  3. #3
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    The union seems OK, but a more portable solution would be to (use the macros you are talking about, but in their absence...) shift values out one at a time, and then you don't have to worry about big/little endianness.
    Mainframe assembler programmer by trade. C coder when I can.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Peel each 8-bit part off:

    Code:
    #define IPCOMP(addr, n) ((addr >> (24 - 8 * n)) & 0xFF)
    
    printf("%d.%d.%d.%d", IPCOMP(addr, 0), IPCOMP(addr, 1), IPCOMP(addr, 2), IPCOMP(addr, 3));
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Which is why using the constructs from socket programming are wisest, in my humble opinion.

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by brewbuck View Post
    Peel each 8-bit part off:

    Code:
    #define IPCOMP(addr, n) ((addr >> (24 - 8 * n)) & 0xFF)
     
    printf("%d.%d.%d.%d", IPCOMP(addr, 0), IPCOMP(addr, 1), IPCOMP(addr, 2), IPCOMP(addr, 3));
    Wrong direction, homie.

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    23
    Wow, quick replies. Thank you!

    Here is the other code I am trying to incorporate.

    Maybe I am doing things wrong since I am a newb - I am trying to break things down one at a time instead of doing the project as a whole. I have a feeling that I am not doing everything correctly. Thanks again for the assistance.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    main()
    {
    int choice;
    
    do
    { printf("Select from one of the choices:\n");
      printf("1.) Convert from 32 bit binary ip form to dotted decimal ip form\n");
      printf("2.) Convert from dotted decimal ip form to 32 bit binary ip form\n");
      printf("3.) Convert a dotted decimal ip form to it's class and display the network portions separately\n");
      printf("4.) Convert from CIDR slash notation to dotted decimal ip form\n");
      printf("5.) Convert from subnet dotted ip form to CIDR slash form\n");
      printf("6.) Quit the the program\n");
    printf("Enter your choice: ");
    scanf(" %d", &choice);
    switch (choice)
      {
    case (1) : printf("1.) Convert from 32 bit binary ip form to dotted decimal ip form\n");
    break;
    case (2) : printf("2.) Convert from dotted decimal ip form to 32 bit binary ip form\n");
    // Initialize the variables
    unsigned long a,b,c,d,base10IP;
    
    // Get the IP address from user
    cout << "\nEnter an IP address in dotted quad notation (x.x.x.x)";
    cout << "\nwith each section seperated by a space: ";
    cin >> a >> b >> c >> d;
    
    // Do calculations to covert IP to base 10
    a *= 16777216;
    b *= 65536;
    c *= 256;
    base10IP = a + b + c + d;
    
    // Output new IP address
    cout << "\nThe converted address is: " << base10IP << '\n';
    break;
    case (3) : printf("3.) Convert a dotted decimal ip form to it's class and display the network portions separately\n");
    break;
    case (4) : printf("4.) Convert from CIDR slash notation to dotted decimal ip form\n");
    break;
    case (5) : printf("5.) Convert from subnet dotted ip form to CIDR slash form\n");
    break;
    case (6) : exit(0);
    break;
    default  : printf("I don't know the ");
               printf("option %d. \n", choice);
               printf("Try again. \n");
               break;
      }
    system("clear");
    } while(1);
    }

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by master5001 View Post
    Wrong direction, homie.
    Why is that?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Oh wait... when I said that to you, I meant to quietly mutter it to myself instead.

  10. #10
    Registered User
    Join Date
    Nov 2008
    Posts
    23
    well my code from decimal to binary didn't work because cout and cin are not found in C but found in C++. Does anybody have any suggestions because I am getting really frustrated??

    I know there were suggestions but there seems to be conflicts back and forth. What should I use?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    In C you would use scanf instead of cin, and printf instead of cout.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Posts
    23
    Well I finally got the code working but I didn't get it to convert to binary

    How can I express this operation of decimal to binary like this.
    ex:
    IP - 172.16.10.15
    If I did each number at a time, like if I started with 172.
    Ton convert 172 to Binary, I would have to:
    1. First divide the number by 2. The remainder will be either 0 or 1.
    2. Write down the remainder.
    3. Divide the remaining number without the remainder by 2. Again, the remainder will be either 1 or 0.
    4. Write down the remainder to the left of the previous remainder.
    5. Repeat this until you end up with 0.

    For 172, the formula would look like this:

    172 / 2 = 86 remainder 0
    86 / 2 = 43 remainder 0
    43 / 2 = 21 remainder 1
    21 / 2 = 10 remainder 1
    10 / 2 = 5 remainder 0
    5 / 2 = 2 remainder 1
    2 / 2 = 1 remainder 0
    1 / 2 = 0 remainder 1

    So the binary number for 172 = 10101100

    For 15:
    If I used a smaller number such as 15, I would have reached 0 before I had 8 bits. If this occurs, I have to fill in the remaining bits with 0s. For example:

    15 / 2 = 7 remainder 1
    7 / 2 = 3 remainder 1
    3 / 2 = 1 remainder 1
    1 / 2 = 0 remainder 1

    Because I got to 0 in only four steps, the remaining bits are 0--so the binary of 15 is 00001111.

    How can I express this in code

    If anybody cares here is the working code - it converts dotted IP to decimal.
    Code:
    case (2) : printf("2.) Convert from dotted decimal ip form to 32 bit binary ip form\n");
    {
              // Initialize the variables
                 unsigned long a,b,c,d,e;
              // Get IP Address from user
              printf("Enter a dotted decimal IP address in dotted quad notation (x.x.x.x)\n");
              printf("with each section seperated by a space: \n");
              scanf(" %a.%b.%c.%d", &firstip, &secondip, &thirdip, &fourthip);
              // Do calculations to convert IP to base 10
              a *= 16777216;
              b *= 65536;
              c *= 256;
              e  = a + b + c + d;
              // The 32 bit binary IP form
              scanf(" %e", &answer);
              // Listing Answer
              printf("\nThe bit binary IP you wanted is listed below.\n");
              printf("Request: %e");
              return 0;
    }
    break;

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Post the code you have thus far for the IP-to-decimal conversion.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  14. #14
    Registered User
    Join Date
    Nov 2008
    Posts
    23
    If anybody wants to know the end code - here it is
    Thanks for the help everyone!

    Code:
    //************************************************************************
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // read an IP address in binary form
    // store it into an array of 4 strings of 8 chars each
    // return 1 if read successfully or 0 if an error occurred
      int readBinary(char bin[4][8]) {
      char binString[80];
      int i, j;
      int nextChar = 0;
      int len;
    
    // read line
      printf("Enter 32-bit IP address in binary form (xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx): ");
      fflush(stdout); //flushes the output, it is needed on some version of linux/unix before scanf
      scanf("%[^\r\n]", binString);
    
    // store binary digits into bin array
      len = strlen(binString);
      for (i=0; i<4; i++) {
        if (nextChar >= len) {
          printf("Invalid input string (too short)\n");
          return 0;
        }
        for (j=0; j<8; j++) {
    // skip spaces
          while (nextChar < len && binString[nextChar] == ' ')
            nextChar++;
    // end of string? break the loop
          if (nextChar >= len) {
            printf("Invalid input string (too short)\n");
            return 0;
          }
          bin[i][j] = binString[nextChar];
          nextChar++;
    // only 0 and 1 accepted
          if (bin[i][j] != '0' && bin[i][j] != '1') {
            printf("Invalid input string (not a binary number)\n");
            return 0;
          }
        }
      }
    
    // return 1 (OK)
      return 1;
    }
    
    // read an IP address in decimal dotted form
    // return 1 if ok or 0 if an error occurs
      int readIPAddress(int ipaddr[]) {
      char decstring[4][4];
      int i;
    
    // read IP address as strings
      printf("Enter 32-bit IP address in dotted decimal notation (xxx.xxx.xxx.xxx): ");
      fflush(stdout);
      if (scanf("%[^.].%[^.].%[^.].%[^\r\n]", decstring[0], decstring[1], decstring[2], decstring[3]) < 4) {
        printf("Invalid input string (wrong IP address format)\n");
        return 0;
      }
    
    // convert each string to integer
      for (i=0; i<4; i++) {
        ipaddr[i] = atoi(decstring[i]);  // atoi converts a string to an integer
        if (ipaddr[i] < 0 || ipaddr[i] > 255) {
          printf("Invalid input string (incorrect numbers for IP address)\n");
          return 0;
        }
      }
    
      return 1;
    }
    
    // read an IP address slash netmask length (CIDR format)
    // return 1 if ok or 0 if an error occurs
    int readIPSlashAddress(int ipaddr[], int *slash) {
      char decstring[4][4];
      char slashstring[3];
      int i;
    
    // read IP address as strings
      printf("Enter IP-address in CIDR notation (xxx.xxx.xxx.xxx/xx): ");
      fflush(stdout);
      if (scanf("%[^.].%[^.].%[^.].%[^/]/%[^\r\n]", decstring[0], decstring[1], decstring[2], decstring[3], slashstring) < 5) {
        printf("Invalid input string (wrong IP address format)\n");
        return 0;
      }
    
    // convert each string to integer
      for (i=0; i<4; i++) {
        ipaddr[i] = atoi(decstring[i]);
        if (ipaddr[i] < 0 || ipaddr[i] > 255) {
          printf("Invalid input string (incorrect numbers for IP address)\n");
          return 0;
        }
      }
    
      *slash = atoi(slashstring);  // a variable and it stores the netmask-length
      if (*slash < 0 || *slash > 32) {
        printf("Invalid input string (invalid netmask length)\n");
        return 0;
      }
    
      return 1;
    }
    
    // read an IP address slash netmask
    // return 1 if ok or 0 if an error occurs
      int readIPMaskAddress(int ipaddr[], int mask[]) {
      char decstring[4][4];
      char maskstring[4][4];
      int i;
    
    // read IP address as strings
      printf("Enter IP-address/subnet you want converted to CIDR slash form (xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx.): ");
      fflush(stdout);
      if (scanf("%[^.].%[^.].%[^.].%[^/]/%[^.].%[^.].%[^.].%[^\r\n]", decstring[0], decstring[1], decstring[2], decstring[3],
          maskstring[0], maskstring[1], maskstring[2], maskstring[3]) < 8) {
        printf("Invalid input string (wrong IP address/netmask format)\n");
        return 0;
      }
    
    // convert each string to integer
       for (i=0; i<4; i++) {
        ipaddr[i] = atoi(decstring[i]);
        if (ipaddr[i] < 0 || ipaddr[i] > 255) {
          printf("Invalid input string (incorrect numbers for IP address)\n");
          return 0;
        }
      }
    
    // convert each string to integer
       for (i=0; i<4; i++) {
        mask[i] = atoi(maskstring[i]);
        if (mask[i] < 0 || mask[i] > 255) {
          printf("Invalid input string (incorrect numbers for netmask)\n");
          return 0;
        }
      }
      return 1;
    }
    
    void convertBinToDec(char bin[4][8], int dec[]) {
    
      int i, j;
    
    // convert each binary group to decimal number
      for (i=0; i<4; i++) {
        dec[i] = 0;
        for (j=0; j<8; j++) {
          dec[i] *= 2;
          if (bin[i][j] == '1')
            dec[i]++;
        }
      }
    
    }
    
    void convertDecToBin(int dec[], char bin[4][9]) {
    
      int i, j;
    
    // convert each decimal group to binary
      for (i=0; i<4; i++) {
        for (j=7; j>=0; j--) {
          bin[i][j] = (dec[i] & 1) + '0';
          dec[i] /= 2;
        }
        bin[i][8] = 0;
      }
    
    }
    
    // show network and host parts
    void showNetworkHost(int ipaddr[], int numNetwork) {
      int i;
    
      printf("Network portion is: ");
      for (i=0; i<=numNetwork; i++)
        printf("%d.", ipaddr[i]);
      printf("\n");
    
      printf("Host portion is: ");
      for (i=numNetwork+1; i<4; i++)
        printf(".%d", ipaddr[i]);
      printf("\n");
    }
    
    void convertCIDRToNetmask(int slash, int mask[]) {
    
    // create binary mask first, then convert to decimal
      char bin[4][8];
      int i, j;
    
    // write 1's while slash is positive, then write 0's
      for (i=0; i<4; i++)
        for (j=0; j<8; j++) {
          if (slash > 0) {
            bin[i][j] = '1';
            slash--;
          }
          else
            bin[i][j] = '0';
        }
    
    // convert to decimal
      convertBinToDec(bin, mask);
    }
    
      int convertNetmaskToCIDR(int mask[], int *slash) {
    // create binary mask first, then convert to slash form
      char bin[4][9];
      int i, j;
      char lastChar;
    
      convertDecToBin(mask, bin);
    
    // add to slash while 1's are found
      lastChar = '1';
      *slash = 0;
      for (i=0; i<4; i++)
        for (j=0; j<8; j++) {
          if (bin[i][j] == '1') {
    // once a zero is found - no more 1's should appear
            if (lastChar == '0') {
              printf("Cannot convert netmask to CIDR notation\n");
              return 0;
            }
            (*slash)++;
          }
          lastChar = bin[i][j];
        }
    
      return 1;
    }
    
    int main()
    {
      int choice;
      char bin[4][8];
      char bin2[4][9];
      int ipaddr[4];
      int mask[4];
      int slash;
    
    // temp string, used when reading - used to skip any remaining input after reading
    // a menu option in the main menu.  The main menu scanf reads an integer.  If a temp
    // string wasn't used, the next scanf trying to read a string would read an empty string 
      char temp[80];
    
      do
      {
        printf("\nSelect from one of the choices:\n\n");
        printf("1) Convert from 32 bit binary ip form to dotted decimal ip form\n");
        printf("2) Convert from dotted decimal ip form to 32 bit binary ip form\n");
        printf("3) Convert a dotted decimal ip form to its class and display the network and host portions separately\n");
        printf("4) Convert from IP/CIDR slash notation to dotted decimal ip form\n");
        printf("5) Convert from IP/subnet dotted ip form to CIDR slash form\n");
        printf("6) Quit the program\n");
        printf("\nEnter your choice: ");
        fflush(stdout);
        scanf("%d", &choice);
        scanf("%[^\n]", temp);
        scanf("%c", temp);
    
        switch (choice)
        {
          case (1) : // Convert from 32 bit binary ip form to dotted decimal ip form
    
                     if (!readBinary(bin))
                       break;
    
                     convertBinToDec(bin, ipaddr);
    
                     // print the resulting IP
                     printf("The address converted to decimal is: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
    
                     break;
    
          case (2) : // Convert from dotted decimal ip form to 32 bit binary ip form
                     if (!readIPAddress(ipaddr))
                       break;
    
                     convertDecToBin(ipaddr, bin2);
    
                     // print the results
                     printf("The address converted to binary is: %8s %8s %8s %8s\n", bin2[0], bin2[1], bin2[2], bin2[3]);
                     break;
    
          case (3) : // Convert a dotted decimal ip form to its class
                     if (!readIPAddress(ipaddr))
                       break;
    
                     if (ipaddr[0] < 128) {
                       printf("This address belongs to class A\n");
                       showNetworkHost(ipaddr, 0);
                     }
                     else if (ipaddr[0] < 192) {
                       printf("This address belongs to class B\n");
                       showNetworkHost(ipaddr, 1);
                     }
                     else if (ipaddr[0] < 224) {
                       printf("This address belongs to class C\n");
                       showNetworkHost(ipaddr, 2);
                     }
                     else if (ipaddr[0] < 240)
                       printf("This address belongs to class D\n");
                     else
                       printf("This address belongs to class E\n");
    
                     break;
          case (4) : // Convert from IP CIDR slash notation of to dotted decimal ip form
                     if (!readIPSlashAddress(ipaddr, &slash))
                       break;
    
                     convertCIDRToNetmask(slash, mask);
    
                     printf("IP/Netmask in dotted decimal IP form: %d.%d.%d.%d/%d.%d.%d.%d\n",
                         ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], mask[0], mask[1], mask[2], mask[3]);
    
                     break;
    
          case (5) : // Convert from IP/subnet form to CIDR slash form
                     if (!readIPMaskAddress(ipaddr, mask))
                       break;
    
                     if (!convertNetmaskToCIDR(mask, &slash))
                       break;
    
                     printf("IP/Netmask-length in CIDR notation: %d.%d.%d.%d/%d",
                         ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], slash);
    
                     break;
    
          case (6) : system("clear"); //clear program
                     exit(0); // close program
    
          default  : printf("I don't know the option %d.\n", choice);
                     printf("Try again.\n");
                     break;
        }
      } while(1);
    }

  15. #15
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    I would highly recommend using the existing libraries that are used for this sort of thing. Please check out the use of

    #include <arpa/inet.h>


    http://www.opengroup.org/onlinepubs/...inet_addr.html

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Porting from 32 bit machine to 64 bit machine!
    By anoopks in forum C Programming
    Replies: 10
    Last Post: 02-25-2005, 08:02 PM
  2. Replies: 7
    Last Post: 12-10-2004, 08:18 AM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. 16 bit or 32 bit
    By Juganoo in forum C Programming
    Replies: 9
    Last Post: 12-19-2002, 07:24 AM