declaring long hex strings?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • arekkusu@mac.com

    #1

    declaring long hex strings?

    Hello, I have the following problem:

    when declaring hex data in C, you typically do something like:
    const char[] = {0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03, 0x04 ... };

    This is quite verbose and makes the source hard to read.

    An alternative is something like
    const char[] = "deadbeef010203 04";

    but this doubles the storage requirements since each nybble is
    converted to an ASCII char.

    Some old assemblers have HEX directives for declaring large chunks of
    raw data. My question is: is there any way to do this in C? Excessive
    preprocessor acrobatics are OK as long as they work in gcc...

    The hex data I have is several thousand strings like:
    CRC(b746de6d) SHA1(ea69f87f84 ded1f0a66457af2 4cbc692e5ff67e3 )

    Really, I just want a preprocessor macro that does a trivial regex like
    s/([a-fA-F0-9][a-fA-F0-9])/0x\1,/ is that possible?

  • Michael Mair

    #2
    Re: declaring long hex strings?

    arekkusu@mac.co m wrote:[color=blue]
    > Hello, I have the following problem:
    >
    > when declaring hex data in C, you typically do something like:
    > const char[] = {0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03, 0x04 ... };[/color]

    Better
    const unsigned char[] = ....
    0x** is an unsigned int value and the conversion to char can cause
    an overflow if char is signed which leads to undefined behaviour.
    [color=blue]
    > This is quite verbose and makes the source hard to read.[/color]

    Indeed.

    [color=blue]
    > An alternative is something like
    > const char[] = "deadbeef010203 04";
    >
    > but this doubles the storage requirements since each nybble is
    > converted to an ASCII char.[/color]

    Nope. C does not specify anything about character encoding;
    we can as well use EBCDIC or anything else. The 4bit nibbles
    are represented by a character which has CHAR_BIT bits.

    [color=blue]
    > Some old assemblers have HEX directives for declaring large chunks of
    > raw data. My question is: is there any way to do this in C? Excessive
    > preprocessor acrobatics are OK as long as they work in gcc...
    >
    > The hex data I have is several thousand strings like:
    > CRC(b746de6d) SHA1(ea69f87f84 ded1f0a66457af2 4cbc692e5ff67e3 )
    >
    > Really, I just want a preprocessor macro that does a trivial regex like
    > s/([a-fA-F0-9][a-fA-F0-9])/0x\1,/ is that possible?[/color]

    I fear you won't get that; the preprocessor cannot split preprocessing
    tokens.

    Some possibilities:
    If you have file I/O on your target system: Store your data chunks
    in text or binary files and retrieve them at runtime. May even make
    the whole thing more flexible.
    Have a look at a general purpose preprocessor or a script language
    with regexps and produce data files which will get converted to
    the required C data which in turn can be #included where appropriate.
    Third: If you are daring, you can fake a preprocesser macro; you "call"
    e.g. const unsigned char[] = HEXARRAY(deadbe ef....);
    and apply, say, a perl script to your source before you go through
    preprocessing and compilation; this is a viable solution if you use
    makefiles.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.

    Comment

    • Andrey Tarasevich

      #3
      Re: declaring long hex strings?

      arekkusu@mac.co m wrote:[color=blue]
      > ...
      > when declaring hex data in C, you typically do something like:
      > const char[] = {0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03, 0x04 ... };
      >
      > This is quite verbose and makes the source hard to read.
      >
      > An alternative is something like
      > const char[] = "deadbeef010203 04";
      >
      > but this doubles the storage requirements since each nybble is
      > converted to an ASCII char.[/color]

      You can also use

      const char[] = "\xde\xad\xbe\x ef\x01\x02\x03\ x04";

      although this is not much less verbose than the original version.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • pete

        #4
        Re: declaring long hex strings?

        Michael Mair wrote:
        [color=blue]
        > 0x** is an unsigned int value and the conversion to char can cause
        > an overflow if char is signed which leads to undefined behaviour.[/color]

        0x01 is an expression of type int, not unsigned.

        Conversion of an out of range value, to a signed integer type,
        is implementation defined, not undefined.

        --
        pete

        Comment

        • Michael Mair

          #5
          Re: declaring long hex strings?

          pete wrote:[color=blue]
          > Michael Mair wrote:
          >[color=green]
          >>0x** is an unsigned int value and the conversion to char can cause
          >>an overflow if char is signed which leads to undefined behaviour.[/color]
          >
          > 0x01 is an expression of type int, not unsigned.
          >
          > Conversion of an out of range value, to a signed integer type,
          > is implementation defined, not undefined.[/color]

          Argh. Note to self: Do not put the standard into some unmarked
          box when moving...
          Right, I don't know what I was thinking (too late for thinking,
          probably). Thank you :-)


          Cheers
          Michael
          --
          E-Mail: Mine is an /at/ gmx /dot/ de address.

          Comment

          • arekkusu@mac.com

            #6
            Re: declaring long hex strings?

            Thanks for the replies.

            It looks like there is no way to trick the preprocessor to do this. :(
            Sadly in my case external files and additional preprocess passes are
            not possible.

            That leaves: ugly code. :(

            Comment

            • Peter Nilsson

              #7
              Re: declaring long hex strings?

              arekkusu@mac.co m wrote:[color=blue]
              > Hello, I have the following problem:
              >
              > when declaring hex data in C, you typically do something like:
              > const char[] = {0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03, 0x04 ... };
              >
              > This is quite verbose and makes the source hard to read.
              >
              > An alternative is something like
              > const char[] = "deadbeef010203 04";
              >
              > but this doubles the storage requirements since each nybble is
              > converted to an ASCII char.
              >
              > Some old assemblers have HEX directives for declaring large chunks of
              > raw data. My question is: is there any way to do this in C? Excessive
              > preprocessor acrobatics are OK as long as they work in gcc...
              >
              > The hex data I have is several thousand strings like:
              > CRC(b746de6d) SHA1(ea69f87f84 ded1f0a66457af2 4cbc692e5ff67e3 )
              >
              > Really, I just want a preprocessor macro that does a trivial regex[/color]
              like[color=blue]
              > s/([a-fA-F0-9][a-fA-F0-9])/0x\1,/ is that possible?[/color]

              If you're willing to split it up, you can do something like...

              #define SHA1(p,q,r,s,t) \
              SPLIT(p), SPLIT(q), SPLIT(r), SPLIT(s), SPLIT(t)

              #define CAT(x,y) x ##y
              #define CAT2(x,y) CAT(x,y)

              #define SPLIT(x) SPLIT4(CAT2(0x0 ,x))
              #define SPLIT4(x) \
              (x >> 24) & 0xFF, \
              (x >> 16) & 0xFF, \
              (x >> 8) & 0xFF, \
              (x ) & 0xFF

              unsigned char x[] =
              { SHA1(ea69f87f, 84ded1f0, a66457af, 24cbc692, e5ff67e3),
              SHA1(deadbeef, aaaaaaaa, 55555555, 12345678, 90abcdef) };

              #include <stdio.h>

              int main(void)
              {
              size_t i;
              for (i = 0; i < sizeof x; i++)
              printf(" %02X", 0u + x[i]);
              puts("");
              return 0;
              }

              --
              Peter

              Comment

              • pete

                #8
                Re: declaring long hex strings?

                Michael Mair wrote:[color=blue]
                >
                > pete wrote:[color=green]
                > > Michael Mair wrote:
                > >[color=darkred]
                > >>0x** is an unsigned int value and the conversion to char can cause
                > >>an overflow if char is signed which leads to undefined behaviour.[/color]
                > >
                > > 0x01 is an expression of type int, not unsigned.
                > >
                > > Conversion of an out of range value, to a signed integer type,
                > > is implementation defined, not undefined.[/color]
                >
                > Argh. Note to self: Do not put the standard into some unmarked
                > box when moving...
                > Right, I don't know what I was thinking (too late for thinking,
                > probably). Thank you :-)[/color]

                You're welcome. I just thought of a C riddle.
                #define A, B, and C, such that this expression
                (A > B && B > C && A == C)
                becomes a constant expression with a value of 1.

                --
                pete

                Comment

                • Ben Pfaff

                  #9
                  Re: declaring long hex strings?

                  pete <pfilandr@minds pring.com> writes:
                  [color=blue]
                  > I just thought of a C riddle.
                  > #define A, B, and C, such that this expression
                  > (A > B && B > C && A == C)
                  > becomes a constant expression with a value of 1.[/color]

                  #define A 1 || (0
                  #define B 0
                  #define C 0)

                  The 1 may be replaced by an arbitrary nonzero value of your choice.
                  Each 0 may be replaced by an arbitrary value of your choice.
                  --
                  "Large amounts of money tend to quench any scruples I might be having."
                  -- Stephan Wilms

                  Comment

                  • Michael Mair

                    #10
                    Re: declaring long hex strings?

                    pete wrote:[color=blue]
                    > Michael Mair wrote:
                    >[color=green]
                    >>pete wrote:
                    >>[color=darkred]
                    >>>Michael Mair wrote:
                    >>>
                    >>>
                    >>>>0x** is an unsigned int value and the conversion to char can cause
                    >>>>an overflow if char is signed which leads to undefined behaviour.
                    >>>
                    >>>0x01 is an expression of type int, not unsigned.
                    >>>
                    >>>Conversion of an out of range value, to a signed integer type,
                    >>>is implementation defined, not undefined.[/color]
                    >>
                    >>Argh. Note to self: Do not put the standard into some unmarked
                    >>box when moving...
                    >>Right, I don't know what I was thinking (too late for thinking,
                    >>probably). Thank you :-)[/color]
                    >
                    >
                    > You're welcome. I just thought of a C riddle.
                    > #define A, B, and C, such that this expression
                    > (A > B && B > C && A == C)
                    > becomes a constant expression with a value of 1.[/color]

                    *g*

                    #include <stdio.h>

                    #define STRINGIZE(s) #s
                    #define STRINGIZE2(s,t) "\""#s ", "#t"\""
                    #define XSTR(s) STRINGIZE(s)
                    #define XSTR2(s) STRINGIZE2(s)
                    #define EVAL \
                    printf("Evaluat es (%s,%s,%s) to %d\n",\
                    XSTR(A),XSTR(B) ,XSTR(C),(A > B && B > C && A == C))
                    #define EVAL2 \
                    printf("Evaluat es (%s,%s,%s) to %d\n",\
                    XSTR(A),XSTR(B) ,XSTR2(C),(A > B && B > C && A == C))

                    int main (void)
                    {
                    #define A 1||-1000
                    #define B -500
                    #define C 0
                    EVAL;
                    #undef A
                    #undef B
                    #undef C
                    #define A -1000
                    #define B -500
                    #define C 0, 1
                    EVAL2;
                    #undef A
                    #undef B
                    #undef C
                    #define A -1000
                    #define B -500
                    #define C 0 ? 0 : 1
                    EVAL;
                    #undef A
                    #undef B
                    #undef C
                    #define A (unsigned) C
                    #define B 0
                    #define C -1
                    EVAL;
                    #undef A
                    #undef B
                    #undef C

                    return 0;
                    }


                    --
                    E-Mail: Mine is an /at/ gmx /dot/ de address.

                    Comment

                    • pete

                      #11
                      Re: declaring long hex strings?

                      Ben Pfaff wrote:[color=blue]
                      >
                      > pete <pfilandr@minds pring.com> writes:
                      >[color=green]
                      > > I just thought of a C riddle.
                      > > #define A, B, and C, such that this expression
                      > > (A > B && B > C && A == C)
                      > > becomes a constant expression with a value of 1.[/color]
                      >
                      > #define A 1 || (0
                      > #define B 0
                      > #define C 0)
                      >
                      > The 1 may be replaced by an arbitrary nonzero value of your choice.
                      > Each 0 may be replaced by an arbitrary value of your choice.[/color]

                      I should have used more parentheses.
                      ((A) > (B) && (B) > (C) && (A) == (C))

                      This is what I had in mind:
                      #define A (0)
                      #define B (-1)
                      #define C (0u)

                      --
                      pete

                      Comment

                      • pete

                        #12
                        Re: declaring long hex strings?

                        Michael Mair wrote:[color=blue]
                        >
                        > pete wrote:[color=green]
                        > > Michael Mair wrote:
                        > >[color=darkred]
                        > >>pete wrote:
                        > >>
                        > >>>Michael Mair wrote:
                        > >>>
                        > >>>
                        > >>>>0x** is an unsigned int value and the conversion to char can cause
                        > >>>>an overflow if char is signed which leads to undefined behaviour.
                        > >>>
                        > >>>0x01 is an expression of type int, not unsigned.
                        > >>>
                        > >>>Conversion of an out of range value, to a signed integer type,
                        > >>>is implementation defined, not undefined.
                        > >>
                        > >>Argh. Note to self: Do not put the standard into some unmarked
                        > >>box when moving...
                        > >>Right, I don't know what I was thinking (too late for thinking,
                        > >>probably). Thank you :-)[/color]
                        > >
                        > >
                        > > You're welcome. I just thought of a C riddle.
                        > > #define A, B, and C, such that this expression
                        > > (A > B && B > C && A == C)
                        > > becomes a constant expression with a value of 1.[/color][/color]
                        [color=blue]
                        > #define A 1||-1000
                        > #define B -500
                        > #define C 0
                        > EVAL;
                        > #undef A
                        > #undef B
                        > #undef C
                        > #define A -1000
                        > #define B -500
                        > #define C 0, 1
                        > EVAL2;
                        > #undef A
                        > #undef B
                        > #undef C
                        > #define A -1000
                        > #define B -500
                        > #define C 0 ? 0 : 1
                        > EVAL;
                        > #undef A
                        > #undef B
                        > #undef C
                        > #define A (unsigned) C
                        > #define B 0
                        > #define C -1[/color]

                        That last set was closest to what I was thinking.
                        Thanks.

                        Comment

                        Working...