0

簡単に言うと、質問は16進言語 C のビット単位の操作に関連しています。OS:リナックス

「長い」16進文字列に対してビットごとの操作を実行したいだけです。私は次のことを試しました:

初挑戦:

オーバーフローのため、次は使用できません。

long  t1 = 0xabefffcccaadddddffff;
and t2 = 0xdeeefffffccccaaadacd;

2 回目の試行: abcdef が 16 進数ではなく文字列として解釈されるため、機能しません

char* t1 = "abefffcccaadddddffff";
char* t2 = "deeefffffccccaaadacd";

int len = strlen(t1);

for (int i = 0; i < len; i++ )
    {
        char exor = *(t1 + i) ^ *(t2 + i);
    printf("%x", exor);
}

誰かがこれを行う方法を教えてください。どうも

4

4 に答える 4

2

通常、ビット演算は非常に簡単に大きな数値に拡張できます。

これを行う最善の方法は、それらを 4 または 8 バイト シーケンスに分割し、それらを uint の配列として格納することです。この場合、これらの特定の文字列には少なくとも 80 ビットが必要です。

AND の場合は、次のように非常に単純です。

unsigned int A[3] = { 0xabef, 0xffcccaad, 0xddddffff };
unsigned int B[3] = { 0xdeee, 0xfffffccc, 0xcaaadacd };
unsigned int R[3] = { 0 };

for (int b = 0; b < 3; b++) {
    R[b] = A[b] & B[b];
}

16 進文字列のスキャンとそれらの出力を含む、より完全な例:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef unsigned int uint;

void long_Print(int size, const uint a[]) {
    printf("0x");
    for (int i = 0; i < size; i++) {
        printf("%x", a[i]);
    }
}

void long_AND(int size, const uint a[], const uint b[], uint r[]) {
    for (int i = 0; i < size; i++) {
        r[i] = a[i] & b[i];
    }
}

// Reads a long hex string and fills an array. Returns the number of elements filled.
int long_Scan(int size, const char* str, uint r[]) {
    int len = strlen(str);
    int ri = size;

    for (const char* here = &str[len]; here != str; here -= 8) {
        if (here < str) {
            char* tmp = (char*)malloc(4);

            tmp[0] = '%';
            tmp[1] = (char)(str - here + '0');
            tmp[2] = 'x';
            tmp[3] = '\0';

            sscanf(str, tmp, &r[ri--]);

            free(tmp);

            break;
        }
        else {
            sscanf(here, "%8x", &r[ri--]);
        }
    }

    for (; ri >= 0; ri--) {
        r[ri] == 0;
    }

    return size - ri;
}

int main(int argc, char* argv[])
{
    uint A[3] = { 0 };
    uint B[3] = { 0 };
    uint R[3] = { 0 };

    long_Scan(3, "abefffcccaadddddffff", A);
    long_Scan(3, "deeefffffccccaaadacd", B);

    long_Print(3, A);
    puts("\nAND");
    long_Print(3, B);
    puts("\n=");

    long_AND(3, A, B, R);
    long_Print(3, R);

    getchar();

    return 0;
}
于 2012-06-19T16:59:32.963 に答える
0

直接使用する代わりにunsigned long、の配列を使用してみることができますunsigned int。それぞれunsigned intが 32 ビットまたは 8 桁の 16 進数を保持します。したがって、定数をそれぞれ 8 桁の 16 進数のチャンクに分割する必要があります。

unsigned int t1[3] = { 0xabef , 0xffcccaad , 0xddddffff };

t1正気を保つために、の最初のエントリに最下位ビットが含まれるように、それらを逆の順序で格納する必要があることに注意してください。

于 2012-06-19T16:59:36.887 に答える
0

任意の長さの整数を処理できるライブラリを使用する必要があります。libgmp の使用を検討してください: http://gmplib.org/

于 2012-06-19T16:55:29.600 に答える
0

ビット単位の操作を行う前に、整数を操作する必要があります。"abeffccc"は整数ではありません。文字列です。strtol 最初に文字列を整数に変換するようなものを使用する必要があります。

値が大きすぎて 64 ビットlong long int(0xFFFFFFFF,FFFFFFFF) に収まらない場合は、Big Integer ライブラリなどを使用して、任意の大きな値をサポートする必要があります。H2CO3 が述べたように、libgmpは C の多数の場合に優れた選択肢です。

于 2012-06-19T16:57:00.157 に答える