Like Tree2Likes
  • 1 Post By nonoob
  • 1 Post By nonoob

How to convert char string of Hex characters to unsigned char string of binary data

This is a discussion on How to convert char string of Hex characters to unsigned char string of binary data within the C Programming forums, part of the General Programming Boards category; I am trying to convert a hexadecimal character array to a binary string (unsigned char) that I can use in ...

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    124

    How to convert char string of Hex characters to unsigned char string of binary data

    I am trying to convert a hexadecimal character array to a binary string (unsigned char) that I can use in crypto functions using Cryptlib or OpenSSL. Basically I have a Hex representation of a key like (02726d40f378e716981c4321d60ba3a3) which as a character string is 32 characters but as a binary string should be 16 bytes.

    The character string is being read in from a file, how can I convert it to its binary representation as an unsigned char array?

    Thanks.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    If it's being read in as characters, read in two at a time and write one byte.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    How?

    The string is being read from a file with fgets() and being stored in a char*

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Then go through the stored string in your char* two at a time and write out one byte at a time.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    I don't think that will work. I'm reading in characters from a file and I need to convert them to binary. I need one character in an unsigned char array to represent one byte (two characters) from a char array.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by maxhavoc View Post
    I don't think that will work. I'm reading in characters from a file and I need to convert them to binary. I need one character in an unsigned char array to represent one byte (two characters) from a char array.
    Of course it's possible; in fact, it's trivial. If you need it spelled out, well, let's spell it out:
    1. Decide the numerical value of the first character in a byte pair (0-15).
    2. Shift this value over four bits to the left.
    3. Add the numerical value of the second character in a byte pair (0-15).
    4. Lather, rinse, repeat.

    If you can come up with a way to only give strtoul two characters at a time, it becomes even more trivial.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    Or do repeated
    Code:
    sscanf(&input_string[i], "%02x", &number);
    byte_string[j] = (unsigned char)number
    every 2 bytes.
    ma1000000000 likes this.

  8. #8
    Registered User
    Join Date
    Jun 2004
    Posts
    124
    Ok, sorry guys, I'm a bit slow. Here's the function I've put together based on nonoob's answer:

    Code:
    void stringToHex(unsigned char* hexString, char* string, int stringLength)
    {
    	unsigned char uChar = 0;
    	
    	for (int x = 0; x < stringLength; x++)
    	{
    		sscanf_s(&string[x], "%02x", &uChar);
    		hexString[x] = uChar;
    	}
    }
    I'm getting a runtime error about stack corruption on uChar. What am I doing wrong?

  9. #9
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    You need to put the result into an int first. Then cast it and assign to char like in my example. Your x should go up by 2 indexing string[]. But where your destination is into hexString the index should go up by 1s.
    ma1000000000 likes this.

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    sscanf is really the best option here, of course - this is just an example of doing it 'by hand':

    Code:
    int
    hex_char_to_binary( char ch, char* ret )
    {
          ch = tolower( ch );      
          if( isdigit( ch ) )
                *ret = ch - '0';             
          else if( ch >= 'a' && ch <= 'f' )
                *ret = ( ch - 'a' ) + 10;  
          else
                return *ret = 0;
          return 1;       
    }
     
    char*
    hex_to_binary_copy( const char* str, char* ret )
    {
          char
                * cpy = ret, 
                low, 
                high;
          if( strlen( str ) &#37; 2 )
          {
                *ret = 0;
                return 0;
          }
          for( const char* ptr = str; *ptr; ptr += 2 )
          {
                if
                ( 
                      !hex_char_to_binary( *ptr, &high ) 
                      ||
                      !hex_char_to_binary( *( ptr + 1 ), &low ) 
                )
                {
                      *ret = 0;
                      return 0;
                }
                *cpy++ = low | ( high << 4 );  
          }
          *cpy = 0;
          return ret;                              
    }
    [edit]
    Or perhaps better yet:
    [/edit]

    Code:
    int
    hex_to_binary( const char* str, void* buf, int* siz )
    {
          char
                * cpy = ( char* )buf, 
                low, 
                high;
          const char
                * ptr = str;
          int
                unused,
                len = strlen( str ), 
                half = len / 2, 
                odd = len % 2;
          if( siz == 0 )
                siz = &unused;
          if( odd )
          {
          /*
                a bit of a hack...
          */
                --ptr;
                ++half;
                high = 0;
                goto skip;
          }
          for( ; *ptr; ptr += 2 )
          {
                if( !hex_char_to_binary( *ptr, &high ) ) 
                      return *siz = 0;
                skip:                  
                if( !hex_char_to_binary( *( ptr + 1 ), &low ) )
                      return *siz = 0;
                *cpy++ = low | ( high << 4 );  
          }
          return *siz = half;                              
    }
    Last edited by Sebastiani; 10-04-2008 at 12:52 PM. Reason: additions, corrections
    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;
    }

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    1

    Thanks Guys

    I know this post was a while ago but thanks for your answers! Specially to nonoob...
    Saved me time and effort...

  12. #12
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,659
    Click the "like" link then, instead of digging up dead threads, as mentioned in the rules as something NOT to do.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  2. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 04:42 PM
  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. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21