2015-07-03 13 views
5

C diliyle neredeyse DES algoritmasını uygulamam ve kodumu optimize etmek istiyorum. Bu yüzden gprof kullandım.Sekiz 6 bitlik birimlerden oluşan 48 bitlik bir dize: her bir birimin orta kısmındaki 4 bitin nasıl hızlı bir şekilde alınacağı

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls us/call us/call name  
51.78  9.32  9.32 8000000  1.17  1.17 sboxes 
34.71  15.57  6.25 8000000  0.78  0.78 extendRight 
    9.90  17.35  1.78 500000  3.56 35.96 operation 
    2.39  17.78  0.43 8000000  0.05  0.05 xorRightAndKey 

gprofsboxes fonksiyon 51.78% zamanın işgal olduğunu göstermektedir: İşte raporun parçasıdır.

sboxes(uchar aucData[6], ...)'da, 48 bit verildi, bunları 8 yuvaya böl, 6 bitlik her yuva. Her yuva için

:

  1. X almak için son biraz ilk bit birleştirmek; Y almak için orta 4 bit elde

  2. ;

  3. (X, Y); Örneğin

, 011110 böylece X = 00 ve Y = 1111 bir yuvadır. Burada (X, Y)

uchar basePos = 0x00; 
for (int i = 0; i < 8; ++i) { 
    x = 0; 
    y = 0; 
    basePos = i * 6; // to locate the slot 
    // combine first bit with last bit 
    if (0 != GET_BIT(aucData, basePos)) { 
     x |= 0x02; 
    } 
    if (0 != GET_BIT(aucData, basePos + 5)) { 
     x |= 0x01; 
    } 
    // get continuous 4 bits 
    for (int j = 1; j <= 4; ++j) { 
     if (0 != GET_BIT(aucData, basePos + j)) { 
      y |= (0x01 << (4 - j)); 
     } 
    } 
    // do something with (x, y) 
} 

Benim soru olduğunu almak için kod edilir

#define LOCATE(ptr, index) (((char *)(ptr))[(index) >> 3]) 

#define GET_BIT(ptr, index) (LOCATE((ptr), (index)) & (((uchar)0x80) >> ((index) % 8))) 

Ve:

Bunu uygulamak için, ben bellekte/SET bit GET için MAKRO yazdım, burada göreceli bir koddur , 48 bit verildi, orta 4 bit mümkün olduğunca hızlı nasıl elde edilir? Arama tablosunda olmadan

+3

Her biri 6 bit ise, bir arama tablosu yapabilir misiniz? – Robinson

+0

Bir seçim: C veya C++. – fuz

+1

Büyük olasılıkla, birden fazla bayt ve bir dizi olmayan bir dizi için ayrı ayrı optimize edilmiş rutinleri yazabilirsiniz. Bu, mevcut bit-by-bit yaklaşımından kaçınacaktır. – usr2564301

cevap

4

:

typedef unsigned long long u64; 

void sboxes(uchar aucData[6]) 
{ 
    u64 v = aucData[0] + (((u64)aucData[1]) << 8) 
    + (((u64)aucData[2]) << 16) 
    + (((u64)aucData[3]) << 24) 
    + (((u64)aucData[4]) << 32) 
    + (((u64)aucData[5]) << 40); 

    for(int i = 0; i < 8; i++) 
    { 
     uchar x = ((v & 1) << 1) | ((v >> 5) & 1); 
     uchar y = ((v >> 1) & 0xF); 
     // do something with x, y 
     printf("x: %hhu, y: %hhu\n", x, y); 

     v >>= 6; 
    } 
} 

Tam uyarı: Ben kriter yoktu. Ama hızlı olmalı. Hala çok yavaşsa, ambalajı daha hızlı bir şekilde u64'e dönüştürebilirsiniz.

+0

koduna göz atmak isteyebilirsiniz. Kodunuz işe yaramaz, düzeltmeye çalıştım ama boşuna. Örneğin, 16 bit 00001111 00001111' verildi, bayt sırasını düşünmeliyim. –

+0

Nasıl çalışmaz? Göndermeden önce test ettim. Soruyu yanlış anlamadığım sürece. Bir yuva ABCDEF bitlerine sahipse, X = FA, Y = BCDE, doğru mu? Girdi dizisinin içeriğinin sıralı olmadığını söylemiyorsan (ör.doğru sıralaması _not_aucData [0] -> aucData [1] -> aucData [2] -> ...) – tohoho

+0

X = AF, ifade yeteneğim için üzgünüm. Eğer uchar aucData [6] = {0xfc, 0x11, 0x22, 0x33, 0x44, 0x55} 'ise,' v' '0x000055443322113fc',' v >> = 6' sonra sağ 6 bit olur. '0xfc' kayboldu, ancak' 0xfc''in sol 6 biti ilk yuvadır. –

İlgili konular