7 /* encode/decode data, hexadecimal style
9 /* #include <hex_code.h>
11 /* VSTRING *hex_encode(result, in, len)
16 /* VSTRING *hex_decode(result, in, len)
21 /* hex_encode() takes a block of len bytes and encodes it as one
22 /* upper-case null-terminated string. The result value is
23 /* the result argument.
25 /* hex_decode() performs the opposite transformation on
26 /* lower-case, upper-case or mixed-case input. The result
27 /* value is the result argument. The result is null terminated,
28 /* whether or not that makes sense.
30 /* hex_decode() returns a null pointer when the input contains
31 /* characters not in the hexadecimal alphabet.
35 /* The Secure Mailer license must be distributed with this software.
38 /* IBM T.J. Watson Research
40 /* Yorktown Heights, NY 10598, USA
49 /* Utility library. */
56 /* Application-specific. */
58 static const unsigned char hex_chars
[] = "0123456789ABCDEF";
60 #define UCHAR_PTR(x) ((const unsigned char *)(x))
62 /* hex_encode - raw data to encoded */
64 VSTRING
*hex_encode(VSTRING
*result
, const char *in
, ssize_t len
)
66 const unsigned char *cp
;
70 VSTRING_RESET(result
);
71 for (cp
= UCHAR_PTR(in
), count
= len
; count
> 0; count
--, cp
++) {
73 VSTRING_ADDCH(result
, hex_chars
[(ch
>> 4) & 0xf]);
74 VSTRING_ADDCH(result
, hex_chars
[ch
& 0xf]);
76 VSTRING_TERMINATE(result
);
80 /* hex_decode - encoded data to raw */
82 VSTRING
*hex_decode(VSTRING
*result
, const char *in
, ssize_t len
)
84 const unsigned char *cp
;
89 VSTRING_RESET(result
);
90 for (cp
= UCHAR_PTR(in
), count
= len
; count
> 0; cp
+= 2, count
-= 2) {
94 if (hex
>= '0' && hex
<= '9')
95 bin
= (hex
- '0') << 4;
96 else if (hex
>= 'A' && hex
<= 'F')
97 bin
= (hex
- 'A' + 10) << 4;
98 else if (hex
>= 'a' && hex
<= 'f')
99 bin
= (hex
- 'a' + 10) << 4;
103 if (hex
>= '0' && hex
<= '9')
105 else if (hex
>= 'A' && hex
<= 'F')
106 bin
|= (hex
- 'A' + 10);
107 else if (hex
>= 'a' && hex
<= 'f')
108 bin
|= (hex
- 'a' + 10);
111 VSTRING_ADDCH(result
, bin
);
113 VSTRING_TERMINATE(result
);
120 * Proof-of-concept test program: convert to hexadecimal and back.
123 #define STR(x) vstring_str(x)
124 #define LEN(x) VSTRING_LEN(x)
126 int main(int unused_argc
, char **unused_argv
)
128 VSTRING
*b1
= vstring_alloc(1);
129 VSTRING
*b2
= vstring_alloc(1);
130 char *test
= "this is a test";
132 #define DECODE(b,x,l) { \
133 if (hex_decode((b),(x),(l)) == 0) \
134 msg_panic("bad hex: %s", (x)); \
136 #define VERIFY(b,t) { \
137 if (strcmp((b), (t)) != 0) \
138 msg_panic("bad test: %s", (b)); \
141 hex_encode(b1
, test
, strlen(test
));
142 DECODE(b2
, STR(b1
), LEN(b1
));
143 VERIFY(STR(b2
), test
);
145 hex_encode(b1
, test
, strlen(test
));
146 hex_encode(b2
, STR(b1
), LEN(b1
));
147 hex_encode(b1
, STR(b2
), LEN(b2
));
148 DECODE(b2
, STR(b1
), LEN(b1
));
149 DECODE(b1
, STR(b2
), LEN(b2
));
150 DECODE(b2
, STR(b1
), LEN(b1
));
151 VERIFY(STR(b2
), test
);
153 hex_encode(b1
, test
, strlen(test
));
154 hex_encode(b2
, STR(b1
), LEN(b1
));
155 hex_encode(b1
, STR(b2
), LEN(b2
));
156 hex_encode(b2
, STR(b1
), LEN(b1
));
157 hex_encode(b1
, STR(b2
), LEN(b2
));
158 DECODE(b2
, STR(b1
), LEN(b1
));
159 DECODE(b1
, STR(b2
), LEN(b2
));
160 DECODE(b2
, STR(b1
), LEN(b1
));
161 DECODE(b1
, STR(b2
), LEN(b2
));
162 DECODE(b2
, STR(b1
), LEN(b1
));
163 VERIFY(STR(b2
), test
);