简体   繁体   English

如何获取和设置char字符串中的位?

[英]How to get and set bits for bits in char string?

Usually bit operations are done in smaller data width such as int, unsigned int or wchar_t. 通常,位操作以较小的数据宽度完成,例如int,unsigned int或wchar_t。 Assuming we want to use the bit strings in a longer format, how to shift, get and set bits for bits in char string? 假设我们要以更长的格式使用位字符串,如何为char字符串中的位移位,获取和设置位?

One way may be to divide and conquer using the conventional method, but how do we ensure the bit carry over? 一种方法可能是使用常规方法进行分而治之,但是我们如何确保位保留下来呢?

Given 特定

#define numberOfState 2000  // number of bits
#define numberOfBitsIn1Byte 8

char* record;

int numberOfCharRequiredToRepresentBits = 
                     ceil(((float)numberOfState/(float)numberOfBitsIn1Byte));


record = (char*) malloc(sizeof(char)*numberOfCharRequiredToRepresentBits);
// record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S"; 
// optional : initialization by doing the set bit according to 
//            input from files. After which, do free(record);

How may we conduct bit operations such as to 我们如何进行位操作,例如

i. shift the *record
ii. get bits from a specific bit position in *record
iii. set bits from a specific bit position in *record

Your bitstream is essentially an array of char. 您的比特流本质上是一个char数组。 So, to perform these operations you work on these char elements. 因此,要执行这些操作,您需要处理这些char元素。

i. 一世。 The shifting operation depends on the number of bits you want to shift. 移位操作取决于您要移位的位数。 If the number is a multiple of 8, it is pretty straightforward, you just copy the elements right of left as many bytes as the number is a multiple of 8. If the number is less than 8, you perform the operation on every element of the array, but you need to or the overflowing bits of the previous element. 如果数字是8的倍数,这很简单,您只需将元素复制到左侧,就跟数字是8的倍数一样多。如果数字小于8,则对元素的每个元素执行操作。数组,但是您需要或上一个元素的溢出位。 For example, in left shift, element i must incorporate the overflowing bits of element i+1, and on right shift, the overflowing bits of element i-1. 例如,在左移时,元素i必须合并元素i + 1的溢出位,而在右移时,元素i-1的溢出位必须合并。 Any other number of bits you want to shift can be achieved by a combination of these two actions. 这两个动作的组合可以实现您要移位的其他位数。 For example, a left shift by 18 is a shift by 16 followed by a shift by 2. In any case, you need to be careful on which side of the bitstring you start, so that you do not lose data. 例如,左移18即是移16再乘以2。在任何情况下,都需要注意从位串的哪一侧开始,以免丢失数据。

ii. II。 In order to get the n-th bit of the bitstream, you access the element with index n/8 (integer division) and get the n%8 bit from it. 为了获得比特流的第n位,请访问索引为n / 8(整数除法)的元素,并从中获取n%8位。

iii. III。 Pretty much the same as ii. 与ii几乎相同。

Please have a try with following code: 请尝试以下代码:

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

int isLittleEndian = 1;

void checkEndian(void)
{
    union  
    {  
        short   inum;  
        char c[sizeof(short)];  
    } un;  

    un.inum=0x0102;  

    if(un.c[0]==1 && un.c[1]==2) 
    {
        printf("big_endian.\n"); 
        isLittleEndian = 0;
    }
    else if(un.c[0]==2 && un.c[1]==1)
    {
        printf("little_endian.\n"); 

        isLittleEndian = 1;
    }

}

void shift_L(char *src, char * dst, int len, int n)
{
    int shiftBytes = n/8;
    int shiftBits = n%8;

    memset(dst, 0, len);
    memcpy(dst, src + shiftBytes, len - shiftBytes);

    if (shiftBits)
    {
        int i = 0;
        unsigned short tmp = 0;

        for ( i = 0; i < len; i++)
        {
            if (isLittleEndian)
            {
                tmp = *(dst+i) << 8 | *(dst+i+1);
                tmp <<= shiftBits;
                *(dst+i) = *((char *)&tmp + 1);
            }
            else
            {
                tmp = *(short *)(dst+i);
                tmp <<= shiftBits;
                *(dst+i) = *((char *)&tmp);
            }
        }
    }
}

void shift_R(char *src, char * dst, int len, int n)
{
    int shiftBytes = n/8;
    int shiftBits = n%8;

    memset(dst, 0, len);
    memcpy(dst + shiftBytes, src, len - shiftBytes);

    if (shiftBits)
    {
        int i = 0;
        unsigned short tmp = 0;

        for ( i = len -1; i >= 0; i--)
        {
            if (isLittleEndian)
            {
                tmp = *(dst+i-1) << 8 | *(dst+i);
                tmp >>= shiftBits;
                *(dst+i) = *((char *)&tmp);
            }
            else
            {
                tmp = *(short *)(dst+i-1);
                tmp >>= shiftBits;
                *(dst+i) = *((char *)&tmp+1);
            }
        }
    }
}

int getBit(char *src, int n)
{
    unsigned char tmp = *(src + n/8);
    unsigned char mask = (0x1 << (8 - n%8 - 1));
    int bit = 0;

    bit =  (tmp & mask) > 0;
    printf("%d", bit);
}

void setBit(char *src, int n, int bit)
{
    unsigned char * pTmp = src + n/8;
    unsigned char mask = (0x1 << (8 - n%8 - 1));

    if (bit)
    {
        *pTmp |= mask;
    }
    else
    {
        *pTmp &= ~mask;
    }
}

void dumpBin(unsigned char *src, int len)
{
    int i = 0;
    int j = 0;
    unsigned char mask = 0;

    for ( i = 0; i < len; i++)
    {
        for ( j = 0; j < 8; j++)
        {
            mask = 0x1 << 8 - j - 1;
            printf("%d",(*(src + i) & mask) > 0); 
        }    
    }
}

void main()
{
    char *record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S";
    //char *record = "NAXHDKA";

    int recordLen = strlen(record);
    char * buffer = NULL;
    int i = 0;

    checkEndian();

    recordLen = recordLen + recordLen%2;
    buffer = malloc(recordLen);
    memcpy(buffer, record, recordLen);

    printf("\n input bit stream:\n");
    dumpBin(buffer, recordLen);


    printf("\n bit stream from getBit:\n");
    for ( i = 0; i < recordLen*8; i++)
    {
        getBit(buffer, i);
    }


    setBit(buffer, 8, 1);
    setBit(buffer, 9, 0);
    setBit(buffer, 10, 1);
    setBit(buffer, 11, 1);
    printf("\n bit stream after setBit:\n");
    dumpBin(buffer, recordLen);


    shift_L(record, buffer, recordLen, 1);
    printf("\n bit stream after shift_L:\n");
    dumpBin(buffer, recordLen);


    shift_R(record, buffer, recordLen, 9);
    printf("\n bit stream after shift_R:\n");
    dumpBin(buffer, recordLen);

    printf("\n");

    free(buffer);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM