2012-06-19 113 views
0

簡要說明:問題與十六進制語言C上的按位運算有關;操作系統:linux長十六進制Linux上的按位運算C

我只想對「長」十六進制字符串做一些按位操作。 我試過如下:

首先嚐試:

我不能使用,因爲溢出的以下內容:

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

第二個嘗試:不工作,因爲ABCDEF被解釋爲字符串,而不是十六進制

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); 
} 

有人請讓我知道如何做到這一點? thx

+0

第一個結果如何溢出? –

+0

編譯後,我得到:「警告:在隱式常量轉換中溢出」 –

+0

@DanF,'log_2(t1)'爲79.它溢出一個64位無符號整數15位。 – Matt

回答

1

按位操作通常很容易擴展到更大的數字。

這樣做的最好方法是將它們分成4或8個字節的序列,並將它們存儲爲一個數組。在這種情況下,這些特定的字符串至少需要80位。

對,這是非常簡單的,是這樣的:

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]; 
} 

一個更完整的例子包括掃描十六進制字符串進行打印:

#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; 
} 
+0

是否需要手動將其分解爲字節序列。不知道我可以拆分字符串,然後將其轉換爲十六進制來存儲它一個int數組,我是嗎? –

+0

@TestTester,我添加了一個基於sscanf的閱讀器來回答:) – Matt

+0

thx爲你的時間 –

0

你當然需要使用一個可以處理任意長整數的庫。考慮使用libgmp:http://gmplib.org/

0

在您可以執行任何類型的按位操作之前,您需要使用整數。 "abeffccc"不是的整數。它是一個字符串。您需要使用諸如strtol 之類的字符串來首先將字符串轉換爲整數。

如果您的值太大而不適合64位long long int(0xFFFFFFFF,FFFFFFFF),那麼您需要使用Big Integer庫或類似的東西來支持任意大的值。如提到H2CO3,libgmp對於C中的大數是一個很好的選擇.

+0

噢,我可以結合你們大多數人所說的:分割成4或8字符串的字符串並存儲在一個數組中(Mat提到上面這個),然後使用strtol將每一個轉換爲整數,然後按位操作並且不需要作爲H2CO3提到的文庫。不知道它是否是最好的,或者它是否可以工作 –

0

,而不是直接使用unsigned long,你可以嘗試使用一排unsigned int。每個unsigned int包含32位或8位十六進制數字。因此,你將不得不您定斬成每8個十六進制數字塊:

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

注意,對於理智,你應該將它們存儲在相反的順序,從而t1的第一個條目包含最低階位。