File: hex.c

package info (click to toggle)
inn2 2.5.2-2~squeeze1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,072 kB
  • ctags: 8,521
  • sloc: ansic: 91,418; sh: 13,249; perl: 12,311; makefile: 2,928; yacc: 868; python: 342; lex: 266
file content (76 lines) | stat: -rw-r--r-- 2,560 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*  $Id: hex.c 7155 2005-04-10 06:27:34Z rra $
**
**  Convert data to or from an ASCII hex representation.
**
**  Converts arbitrary binary data to or from a representation as an ASCII
**  string of hex digits.  Used primarily for converting MD5 hashes into a
**  human-readable value.  For backward-compatibility reasons, capital letters
**  are used for hex digits > 9.
*/

#include "config.h"
#include "clibrary.h"
#include "inn/utility.h"

/*
**  Convert data to an ASCII hex representation.  The result will be stored in
**  buffer and nul-terminated.  buflen is the length of the buffer, which must
**  be at least 2 * length + 1 to hold the full representation.  If it is not
**  long enough, the result will be truncated but buffer will still be
**  nul-terminated.
*/
void
inn_encode_hex(const unsigned char *data, size_t length, char *buffer,
               size_t buflen)
{
    static const char hex[] = "0123456789ABCDEF";
    const unsigned char *p;
    unsigned int i;

    if (buflen == 0)
        return;
    for (p = data, i = 0; i < length && (i * 2) < (buflen - 1); p++, i++) {
        buffer[i * 2]       = hex[(*p & 0xf0) >> 4];
        buffer[(i * 2) + 1] = hex[(*p & 0x0f)];
    }
    if (length * 2 > buflen - 1)
        buffer[buflen - 1] = '\0';
    else
        buffer[length * 2] = '\0';
}


/*
**  Convert data from an ASCII hex representation.  No adjustment is made for
**  byte order.  The conversion stops at the first character that is not a
**  valid hex character.  If there are an uneven number of valid input
**  characters, the input is zero-padded at the *end* (so the string "F" is
**  equivalent to the string "F0").  Lowercase hex digits are tolerated, even
**  though inn_encode_hex doesn't produce them.  buflen is the length of the
**  output buffer and must be at least (input - 1) / 2.  If it is too short
**  to hold the full data, the result will be truncated.
*/
void
inn_decode_hex(const char *data, unsigned char *buffer, size_t buflen)
{
    const char *p;
    unsigned int i;
    unsigned char part;

    if (buflen == 0)
        return;
    memset(buffer, 0, buflen);
    for (p = data, i = 0; (i / 2) < buflen; p++, i++) {
        if (data[i] >= '0' && data[i] <= '9')
            part = data[i] - '0';
        else if (data[i] >= 'A' && data[i] <= 'F')
            part = data[i] - 'A' + 10;
        else if (data[i] >= 'a' && data[i] <= 'f')
            part = data[i] - 'a' + 10;
        else
            return;
        if (i % 2 == 0)
            part <<= 4;
        buffer[i / 2] |= part;
    }
}