在c语言中如何将一个十六进制字符串与另一个十六进制字符串异或

在c语言中如何将一个十六进制字符串与另一个十六进制字符串异或,c,string,C,String,代码固定 例如: argv[1] = "ABCDEF0123456789" argv[2] = "FEDCBA9876543210" desired output: "5511559955115599" 我正在尝试与calculator->hex xor hex=new hex='0'&&c='A'&&c='A'&&c相同的方法,我认为您需要以完全不同的方式来处理这个过程。我认为没有理由使用quads和16路if/else if/../else是可怕的(至少它应该是一个使用quads的循环

代码固定

例如:

argv[1] = "ABCDEF0123456789" 
argv[2] = "FEDCBA9876543210"

desired output: "5511559955115599"

我正在尝试与calculator->hex xor hex=new hex='0'&&c='A'&&c='A'&&c相同的方法,我认为您需要以完全不同的方式来处理这个过程。我认为没有理由使用
quads
和16路
if/else if/../else
是可怕的(至少它应该是一个使用
quads
的循环)。然而,这真的没有必要

鉴于您正在处理用户输入,并且用户是恶意的,代码需要处理数据中不是十六进制数字的字符,以及字符串长度不匹配等。这会产生比操作代码更多的错误检查代码,但这并不少见

#include "stderr.h"
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

typedef unsigned char Uchar;

static inline int hexval(Uchar c)
{
    assert(isxdigit(c));
    if (isdigit(c))
        return c - '0';
    else if (c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    else if (c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    else    // Only used if assert is disabled with -DNDEBUG
        return -1;
}

static const Uchar hexdigits[] = "0123456789ABCDEF";
static inline Uchar hexdigit(int hexval)
{
    assert(hexval >= 0 && hexval < 16);
    return hexdigits[hexval];
}

static int xor_hex_strings(const char *h1, const char *h2, char *x3)
{
    assert(strlen(h1) == strlen(h2));
    const Uchar *s1 = (Uchar *)h1;
    const Uchar *s2 = (Uchar *)h2;
    while (*s1 != '\0')
    {
        Uchar u1 = *s1++;
        Uchar u2 = *s2++;
        assert(isxdigit(u1));
        assert(isxdigit(u2));
        *x3++ = hexdigit(hexval(u1) ^ hexval(u2));
    }
    *x3 = '\0';
    return 0;
}

static void check_hex(const char *hexstr)
{
    const Uchar *s = (Uchar *)hexstr;
    while (*s != '\0')
    {
        Uchar c = *s++;
        if (!isxdigit(c))
            err_error("Character %c in '%s' is not a hex digit\n", c, hexstr);
    }
}

int main(int argc, char **argv)
{
    err_setarg0(argv[0]);
    if (argc != 3)
        err_usage("hex-string1 hex-string2");
    size_t len1 = strlen(argv[1]);
    size_t len2 = strlen(argv[2]);
    if (len1 != len2)
        err_error("hex strings are not the same length (%zu for '%s' vs %zu for '%s')\n",
                  len1, argv[1], len2, argv[2]);
    check_hex(argv[1]);
    check_hex(argv[2]);

    char xor[len1 + 1];
    if (xor_hex_strings(argv[1], argv[2], xor) != 0)
        return 1;

    printf("%s\n%s\n%s\n", argv[1], argv[2], xor);
    return 0;
}
示例测试脚本的输出:

cat <<'EOF' |
0123456789abcdef FEDCBA9876543210
123456789abcdef0 FEDCBA9876543210
23456789abcdef01 FEDCBA9876543210
3456789abcdef012 FEDCBA9876543210
456789abcdef0123 FEDCBA9876543210
56789abcdef01234 FEDCBA9876543210
6789abcdef012345 FEDCBA9876543210
789abcdef0123456 FEDCBA9876543210
89abcdef01234567 FEDCBA9876543210
9abcdef012345678 FEDCBA9876543210
abcdef0123456789 FEDCBA9876543210
bcdef0123456789a FEDCBA9876543210
cdef0123456789ab FEDCBA9876543210
def0123456789abc FEDCBA9876543210
ef0123456789abcd FEDCBA9876543210
f0123456789abcde FEDCBA9876543210
EOF

while read a b
do
    xr53 "$a" "$b"
    echo "----------------"
done
0123456789abcdef
FEDCBA9876543210
FFFFFFFFFFFFFFFF
----------------
123456789abcdef0
FEDCBA9876543210
ECE8ECE0ECE8ECE0
----------------
23456789abcdef01
FEDCBA9876543210
DD99DD11DD99DD11
----------------
3456789abcdef012
FEDCBA9876543210
CA8AC202CA8AC202
----------------
456789abcdef0123
FEDCBA9876543210
BBBB3333BBBB3333
----------------
56789abcdef01234
FEDCBA9876543210
A8A42024A8A42024
----------------
6789abcdef012345
FEDCBA9876543210
9955115599551155
----------------
789abcdef0123456
FEDCBA9876543210
8646064686460646
----------------
89abcdef01234567
FEDCBA9876543210
7777777777777777
----------------
9abcdef012345678
FEDCBA9876543210
6460646864606468
----------------
abcdef0123456789
FEDCBA9876543210
5511559955115599
----------------
bcdef0123456789a
FEDCBA9876543210
42024A8A42024A8A
----------------
cdef0123456789ab
FEDCBA9876543210
3333BBBB3333BBBB
----------------
def0123456789abc
FEDCBA9876543210
202CA8AC202CA8AC
----------------
ef0123456789abcd
FEDCBA9876543210
11DD99DD11DD99DD
----------------
f0123456789abcde
FEDCBA9876543210
0ECE8ECE0ECE8ECE
----------------

测试很重要。我设法将十六进制数字字符串误键入为
“0123456789ABCEDF”
,但测试表明存在问题,
0^E
的输出应该是
E
,而不是
D
,反之亦然。

您是否使用了调试器来跟踪程序的执行情况?如果您需要帮助,请描述您的程序的输入、预期输出和实际输出。请修改代码的缩进,使其更具可读性(只需将每个函数中的代码缩进一级即可)。我已经整理好了代码,您的主要问题是您忘记了在每个字符串的末尾添加
'\0'
,因此您应该使用
char strBin1[5],等等。你为什么不把每个半字节转换成int,对int进行异或运算,然后根据它生成输出?@DavidC.Rankin-谢谢你的提醒。我会在适当的时候更新。
0123456789abcdef
FEDCBA9876543210
FFFFFFFFFFFFFFFF
----------------
123456789abcdef0
FEDCBA9876543210
ECE8ECE0ECE8ECE0
----------------
23456789abcdef01
FEDCBA9876543210
DD99DD11DD99DD11
----------------
3456789abcdef012
FEDCBA9876543210
CA8AC202CA8AC202
----------------
456789abcdef0123
FEDCBA9876543210
BBBB3333BBBB3333
----------------
56789abcdef01234
FEDCBA9876543210
A8A42024A8A42024
----------------
6789abcdef012345
FEDCBA9876543210
9955115599551155
----------------
789abcdef0123456
FEDCBA9876543210
8646064686460646
----------------
89abcdef01234567
FEDCBA9876543210
7777777777777777
----------------
9abcdef012345678
FEDCBA9876543210
6460646864606468
----------------
abcdef0123456789
FEDCBA9876543210
5511559955115599
----------------
bcdef0123456789a
FEDCBA9876543210
42024A8A42024A8A
----------------
cdef0123456789ab
FEDCBA9876543210
3333BBBB3333BBBB
----------------
def0123456789abc
FEDCBA9876543210
202CA8AC202CA8AC
----------------
ef0123456789abcd
FEDCBA9876543210
11DD99DD11DD99DD
----------------
f0123456789abcde
FEDCBA9876543210
0ECE8ECE0ECE8ECE
----------------