2016-03-21 3 views
0

私はunsigned char *Bufferを持っていますが、その中には4バイトしか入っていません。円内シフトCの4バイト以内の28ビット

私は残りの4ビットを無視しながら28ビットの循環シフトを行う関数を作成しようとしています。例えば

、I *はバッファ内の次た1111000011001100101010100000

1110000110011001010101010000

Iを作り、私は28ビットの1ビット循環シフトを残したいと言います私はシフトを得る方法、最後の4ビットを無視する方法、プログラムの初期に設定された変数に応じて1,2,3、または4ビットのいずれかをシフトする能力を理解することができません。

これについての助けがあれば、壊れてしまうでしょう!前もって感謝します。

+1

の下位ビットに格納されていると仮定 '1111000011001100101010100000'の左循環シフトは、実際には' 1110000110011001010101010001'であることが想定されていませんか?それとも、「円形」の部分を意味するのではないですか? – Tibrogargan

+0

あなたは何を無視していいですか?私たちはそこに何かを置く必要がありますか?いくつかのコードは素晴らしいでしょう。 –

+0

この例では、左右両端から1ビットをトリムします。ビットシフトとビットマスクを見てみると、 'num >> 4'が必要になるかもしれません。 – ZachB

答えて

0

まず、あなたは、あなたがxビットで、残りの28ビットの循環シフトを実行することができ、トップ4の最上位ビット

*(buffer + 3) &= 0x0F; 

をマスクします。

注:4つのバイトが含まれています。これは、リトルエンディアンアーキテクチャのために動作します(x86のPCのほとんどのマイクロコントローラ)

-1

[...]が、唯一の28それらの[...]

私はそれを得ましたが、...

私はあなたの例の2番目の数字を間違って入力したと思います。または、左から4ビットを無視すると、となり、実際には24ビットでインターレースされていますか?とにかく:

Circular shift in cと同じ原理を使用します。

これまでにバッファを32ビットの算術型に変換する必要があります。たぶん、uint32_tは必要なものですか?

バッファーはどこに価値をもたらしましたか?エンディアンについて考える必要があるかもしれません。

+0

バッファの値は次のとおりです。 'unsigned int byteArray [8]; \t int i; \t size_t keyLen = strlen(keyInput); \t if(keyLen> 16){ \t \t fprintf(stderr、 "無効なキーの長さ。\ n"); \t \t exit(-1); \t}の (i = 0; iは8 <; iは++){ のsscanf(keyInput + 2 * I、 "%の02X"、&BYTEARRAY [I])。 バッファ[i] = byteArray [i]; } ' バッファはunsigned char *バッファ= malloc(8 * sizeof(char)); – TyrantUT

1

一度に1ビットが、this articleに基づいて、これは

uint32_t csl28(uint32_t value) { 
    uint32_t overflow_mask = 0x08000000; 
    uint32_t value_mask = 0x07FFFFFF; 
    return ((value & value_mask) << 1) | ((value & overflow_mask) >> 27); 
} 

uint32_t csr28(uint32_t value) { 
    uint32_t overflow_mask = 0x00000001; 
    uint32_t value_mask = 0x0FFFFFFE; 
    return ((value & value_mask) >> 1) | ((value & overflow_mask) << 27); 
} 

28ビット循環シフトを行う別のバージョン、。これは、任意に広いビットフィールド(幅)内の任意の数のビット(カウント)をシフトする。 23ビット幅のフィールドに値5ビットを左シフトするには:rotl32(value、5、23);

uint32_t rotl32 (uint32_t value, uint32_t count, uint32_t width) { 
    uint32_t value_mask = ((uint32_t)~0) >> (CHAR_BIT * sizeof(value) - width); 
    const uint32_t mask = (width-1); 
    count &= mask; 
    return value_mask & ((value<<count) | (value>>((-count) & mask))); 
} 

uint32_t rotr32 (uint32_t value, uint32_t count, uint32_t width) { 
    uint32_t value_mask = ((uint32_t)~0) >> (CHAR_BIT * sizeof(value) - width); 
    const uint32_t mask = (width-1); 
    count &= mask; 
    return value_mask & ((value>>count) | (value<<((-count) & mask))); 
} 

上記機能

値が「値」

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

const char *uint32_to_binary(uint32_t x) 
{ 
    static char b[33]; 
    b[0] = '\0'; 

    uint32_t z; 
    for (z = 0x80000000; z > 0; z >>= 1) 
    { 
     strcat(b, ((x & z) == z) ? "1" : "0"); 
    } 

    return b; 
} 

uint32_t reverse(uint32_t value) 
{ 
    return (value & 0x000000FF) << 24 | (value & 0x0000FF00) << 8 | 
      (value & 0x00FF0000) >> 8 | (value & 0xFF000000) >> 24; 
} 

int is_big_endian(void) 
{ 
    union { 
     uint32_t i; 
     char c[4]; 
    } bint = {0x01020304}; 

    return bint.c[0] == 1; 
} 

int main(int argc, char** argv) { 
    char b[] = { 0x98, 0x02, 0xCA, 0xF0 }; 
    char *buffer = b;   

    //uint32_t num = 0x; 
    uint32_t num = *((uint32_t *)buffer); 
    if (!is_big_endian()) { 
     num = reverse(*((uint32_t *)buffer)); 
    } 
    num >>= 4; 
    printf("%x\n", num); 

    for(int i=0;i<5;i++) { 
     printf("%s\n", uint32_to_binary(num)); 
     num = rotl32(num, 3, 28); 
    } 
    for(int i=0;i<5;i++) { 
     //printf("%08x\n", num); 
     printf("%s\n", uint32_to_binary(num)); 
     num = rotr32(num, 3, 28); 
    } 

    unsigned char out[4]; 
    memset(out, 0, sizeof(unsigned char) * 4); 
    num <<= 4; 
    if (!is_big_endian()) { 
     num = reverse(num); 
    } 
    *((uint32_t*)out) = num; 
    printf("[ "); 
    for (int i=0;i<4;i++) { 
     printf("%s0x%02x", i?", ":"", out[i]); 
    } 
    printf(" ]\n"); 
} 
+0

これはうまくいくかもしれません。病気はそれを与える。 以下の最後の答えに関しては、 11110000110011001010101000000000の文字が32ビットあり、最後の4ビットは無視されました。 左にシフトすると1になる1110000110011001010101000001 これは右端の4ビットのミスタイプです – TyrantUT

+0

私は自分のコード内でこれを実装できないようです。 はunsigned char型である*バッファを、貸し付けは、あなたが見ることができるように、1が32バイトを持って進 に '0011000000000101100101011110000' または ' 9802CAF0'が含まれています。私はマスクを解除し、最後の0、またはビットの最後の0000を完全に無視する必要があります。残りの部分を循環シフトします。ここにあるコードがうまくいくかもしれないと確信しています。私は自分のコードに実装する方法を知りません。可能であれば、それをvoid()関数に入れたいと思っています。 – TyrantUT

+0

データがどのように格納されているかは不明です。あなたは1と0の文字列を格納していますか? (i..eあなたの文字列は文字通り '" 0011000000000101100101011110000 "'ですか?)。または、16進数の値を持っていますか?すなわち、あなたのchar *は本当に '[0x98、0x02、0xCA、0xF0]'を保持する4文字の配列ですか?後でこれを行うことができます: 'uint32_t val = *((uint32 *)buffer)>> 4'; (エンディアンが悲しみを引き起こすかもしれない) – Tibrogargan

関連する問題