将十六进制数字的char []转换为对应于ascii表中十六进制数字的字母的char []并将其反转

时间:2012-11-12 12:58:12

标签: c++

我有一个char a[]十六进制字符,如下所示:

  

“315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e”

我想将它转换为对应于每个十六进制数字的字母,如下所示:

68656c6c6f = hello

并将其存储在char b[]中,然后执行相反的操作

我不想要一段代码,我想要解释,使用了哪些库以及如何使用它。

由于

6 个答案:

答案 0 :(得分:2)

将十六进制字符串转换为字符串可以通过使用std::substr获取十六进制字符串的后两个字符,然后使用std::stoi将子字符串转换为整数来完成。这可以转换为添加到std::string的字符。 std::stoi函数仅限C ++ 11,如果您没有它,则可以使用例如std::strtol

为了反过来你循环输入字符串中的每个字符,将其转换为整数并将其放在std::ostringstream前面,操纵器将其显示为two-digit,{{3 }} zero-prefixed。附加到输出字符串。

如果需要,使用hexadecimal number获取旧式C char指针。

没有外部库,只使用C ++标准库。

答案 1 :(得分:2)

假设您正在谈论ASCII代码。好吧,第一步是找到b的大小。假设你有2个十六进制数字的所有字符(例如, tab 将是09),那么b的大小就是strlen(a) / 2 + 1

完成后,您需要查看a,2乘2的字母,将它们转换为整数值并将其存储为字符串。写成一个公式:

b[i] = (to_digit(a[2*i]) << 4) + to_digit(a[2*i+1]))

其中to_digit(x)'0'-'9'转换为0-9'a'-'z''A'-'Z'转换为10-15

请注意,如果0x10以下的字符只显示一个字符(我能想到的唯一一个字符是 tab ,那么不要使用2*i作为{的索引{1}},您应该在循环中保留a,如果next_index则添加2,否则添加1。在后一种情况下,a[next_index] < '8'

此操作的反向非常相似。每个字符b[i] = to_digit(a[next_index])都写为:

b[i]

其中a[2*i] = to_char(b[i] >> 4) a[2*i+1] = to_char(b[i] & 0xf) to_char相反。

答案 2 :(得分:1)

正向:

  1. 从输入中读取两个十六进制字符。
  2. 转换为int(0..255)。 (提示:sscanf是单向的)
  3. 将int追加到输出字符数组
  4. 重复1-3直到离开字符。
  5. Null终止数组
  6. 反向:

    1. 从数组中读取单个字符
    2. 转换为2个十六进制字符(提示:sprintf是单向的)。
    3. 从(2)到最终输出字符串缓冲区的Concat缓冲区。
    4. 重复1-3直到离开字符。
    5. 几乎忘了提。 stdio.h和常规C运行时只需要假设您正在使用sscanfsprintf。您也可以创建一对转换表,从根本上加快转换速度。

答案 3 :(得分:0)

每个十六进制数字对应4位,因为4位有16种可能的位模式(并且有16个可能的十六进制数字,每个数字代表一个唯一的4位模式)。

因此,两个十六进制数字对应8位。

现在大多数计算机(某些德州仪器的数字信号处理器都是例外),C ++ char为8位。

这意味着每个C ++ char由2个十六进制数字表示。

因此,只需一次读取两个十六进制数字,使用例如转换为int istringstream,将其转换为char,并将每个char值附加到std::string

另一个方向正好相反,但有一个转折。

由于char在大多数系统上都已签名,因此您需要先转换为unsigned char,然后再将该值转换为十六进制数字。

答案 4 :(得分:0)

可以使用hex来完成与十六进制的转换,例如

cout << hex << x;
cin >> hex >> x;

对于x的合适定义,例如int x

这也适用于字符串流。

答案 5 :(得分:0)

这是一个简单的代码来完成这个技巧:

unsigned int hex_digit_value(char c)
{
    if ('0' <= c && c <= '9') { return c - '0'; }
    if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
    if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
    return -1;
}

std::string dehexify(std::string const & s)
{
    std::string result(s.size() / 2);

    for (std::size_t i = 0; i != s.size(); ++i)
    {
        result[i] = hex_digit_value(s[2 * i]) * 16
                  + hex_digit_value(s[2 * i + 1]);
    }

    return result;
}

<强>用法:

char const a[] = "12AB";

std::string s = dehexify(a);

备注:

  • 正确的实现会添加检查输入字符串长度是偶数,并且每个数字实际上都是有效的十六进制数字。

  • 去己化与ASCII无关。它只是将任何六角形的半字节序列转换为字节序列。我只是使用std::string作为方便的“字节容器”,这正是它的原样。

  • SO上有几十个答案,告诉你如何走另一条路;只需搜索“hexify”。