位操作函数没有给出所需的结果

问题描述

我正在尝试编写一个函数,该函数采用 const char 数组,对于每个字节,我试图获取这些位并将它们分散到 4 个字节中,其中这些位被分配给 4 个字节中的第 2 位和第 5 位,

int encryptDataAndSend(const char *logName,const char *data)
{
  const int len = strlen(data);
  printf("data length: %d \n",strlen(data));
  char encryptedData[len * 4 + 1];
  for (uint8_t i = 0; i < len; i++)
  {
    uint8_t v1 = 255;
    uint8_t v2 = 255;
    uint8_t v3 = 255;
    uint8_t v4 = 255;

    int bit0 = data[i] & (1 << 0);
    int bit1 = data[i] & (1 << 1);
    int bit2 = data[i] & (1 << 2);
    int bit3 = data[i] & (1 << 3);
    int bit4 = data[i] & (1 << 4);
    int bit5 = data[i] & (1 << 5);
    int bit6 = data[i] & (1 << 6);
    int bit7 = data[i] & (1 << 7);

    char temp[4] = {0};

    printf("char is %d \n",data[i]);
    printf("bits: %d %d %d %d %d %d %d %d \n",bit7,bit6,bit5,bit4,bit3,bit2,bit1,bit0);

    v1 = (v1 & ~(1 << 2)) | (bit0 << 2);
    v1 = (v1 & ~(1 << 5)) | (bit1 << 5);
    printf("v1 : %d \n",v1);
    v2 = (v2 & ~(1 << 2)) | (bit2 << 2);
    v2 = (v2 & ~(1 << 5)) | (bit3 << 5);
    printf("v2 : %d \n",v2);
    v3 = (v3 & ~(1 << 2)) | (bit4 << 2);
    v3 = (v3 & ~(1 << 5)) | (bit5 << 5);
    printf("v3 : %d \n",v3);
    v4 = (v4 & ~(1 << 2)) | (bit6 << 2);
    v4 = (v4 & ~(1 << 5)) | (bit7 << 5);
    printf("v4 : %d \n",v4);
    temp[0] = v1;
    temp[1] = v2;
    temp[2] = v3;
    temp[3] = v4;
    memcpy(encryptedData + 4 * i,temp,4);
    // encryptedData[len * 4] = 0;
  }
  printf("encrypted data: %s",encryptedData);
  const int txBytes = uart_write_bytes(UART_NUM_2,encryptedData,strlen(encryptedData));
  ESP_LOGI(logName,"Wrote %d bytes",txBytes);
  ESP_LOG_BUFFER_HEX("SENDDATA_TAG",txBytes);
  return txBytes;
}

调用函数的方式是

encryptDataAndSend(TX_TASK_TAG,"BF");

所以结果应该是8个字节,其中B的8位被分成4个字节放在新字节的第2和第5位位置,然后F的8位被分成4个字节放在新字节的第 2 和第 5 位。

目前我没有得到正确的结果,我总是得到相同的数字,位设置和检查是否正确,任何帮助将不胜感激!

解决方法

查看输出:

data length: 2 
char is 66 
bits: 0 64 0 0 0 0 2 0 
v1 : 219 
v2 : 219 
v3 : 219 
v4 : 219 
char is 70 
bits: 0 64 0 0 0 4 2 0 
v1 : 219 
v2 : 219 
v3 : 219 
v4 : 219 

您的 bit0 ... bit7 变量包含设置的位的,例如 bit6 的值为 64,即位 6 bit6 已设置。当您稍后尝试将该值推送到目的地时:

v4 = (v4 & ~(1 << 2)) | (bit6 << 2);

bit6 << 2 的值为 256,即设置了第 9 位,然后将其 OR 到 v4

如果设置或未设置相关位,您的 bitn 变量应包含 0 或 1:

int bit0 = (data[i] & (1 << 0)) != 0;
int bit1 = (data[i] & (1 << 1)) != 0;
int bit2 = (data[i] & (1 << 2)) != 0;
int bit3 = (data[i] & (1 << 3)) != 0;
int bit4 = (data[i] & (1 << 4)) != 0;
int bit5 = (data[i] & (1 << 5)) != 0;
int bit6 = (data[i] & (1 << 6)) != 0;
int bit7 = (data[i] & (1 << 7)) != 0;

输出(带有额外的十六进制打印):

data length: 2 
char is 66 
bits: 0 1 0 0 0 0 1 0 
v1 : 251 fb 
v2 : 219 db 
v3 : 219 db 
v4 : 223 df 
char is 70 
bits: 0 1 0 0 0 1 1 0 
v1 : 251 fb 
v2 : 223 df 
v3 : 219 db 
v4 : 223 df 

此外,您试图将 encryptedData 打印为字符串并对其调用 strlen,但您没有在其上放置空终止符(尽管您似乎有一个语句要做注释掉了)。既然你知道你的字节数组有多长,只需使用 len * 4 而不是 strlen(encryptedData)