如何在 C+python+UART 中正确表示单词?
How to have the correct representation of words in C+python+UART?
在串行通信中,我需要将密文从python发送到能够使用C读取的UART。
首先,在python端使用这个技巧:
ciphertext=(b'\x24\x70\xb4\xc5\x5a\xd8\xcd\xb7\x80\x6a\x7b\x00\x30\x69\xc4\xe0\xd8')
ser.write(ciphertext)
在C端,我把接收到的密文放在一个buffer中。我测试如果第一个字节24,数据包的开始:
if (buffer_RX[0]=='\x24')
{
for (i=1;i<=17;i++) //sizeof(buffer_RX)==17
{
printf("%x \n",buffer_RX[i]);
}
}
else {
printf("It is not a packet!");
}
我得到的结果是:
70
b4
c5
5a
d8
cd
b7
80
6a
7b
0
30
69
c4
e0
d8
所以我有两个问题,
- 拳头是为什么 \x00
以这种方式显示,我的意思是只有一个零 0?
- 第二个是我怎么能有同样的表示:
const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};
如果我认为这是字节之间的连接,我的意思是可能是:
unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];
但我不确定,我认为我有语法错误。
此表示将帮助我继续下一步。但是我不知道怎么才能得到它。
如果您想从 1 字节块创建 4 字节长的数据。
const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};
仅对字节进行或操作是不够的,您必须将它们移动到正确的位置。
你目前在做什么,(注意你已经过度索引 plaintext[1]
这应该是 plaintext[0]
):
unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];
在内存中有这个结果,假设int
是32位,4字节长:
--------------------------------------------------------------------------------
| 3. byte | 2. byte | 1. byte | 0. byte |
--------------------------------------------------------------------------------
| 0x00 | 0x00 | 0x00 | buffer_RX[3] | buffer_RX[4] | buffer_RX[5] |
--------------------------------------------------------------------------------
因此您必须首先使用左移运算符将适当的字节移动到正确的位置 <<
,然后对之后的字节进行或运算。
这是一个例子:
#include <stdio.h>
int main()
{
unsigned char buffer_RX[4];
buffer_RX[0] = 0x70;
buffer_RX[1] = 0xb4;
buffer_RX[2] = 0xc5;
buffer_RX[3] = 0x5a;
unsigned int plaintext[1];
plaintext[0] = (buffer_RX[0]<<24) | (buffer_RX[1]<<16) | (buffer_RX[2]<<8) | buffer_RX[3];
printf("plaintext: %08x\n", plaintext[0]);
return 0;
}
输出:
记忆中:
----------------------------------------------------------------------
| 3. byte | 2. byte | 1. byte | 0. byte |
----------------------------------------------------------------------
| buffer_RX[0] | buffer_RX[1] | buffer_RX[2] | buffer_RX[3] |
----------------------------------------------------------------------
你可以看到 buffer_RX[0]
已经移动了 24 ,这是 3 个字节,所以它跳过前三个单元格,跳到最后一个。
buffer_RX[1]
by 16 这是 2 个字节,所以它跳到前两个,buffer_RX[2]
by 8 这是 1 个字节,所以它跳过第一个。并且 buffer_RX[3]
没有移动,因为它转到了第一位。
关于0x00
,它在8位上表示为零。如果您打印它,那将只是 0。如果您打印 0x0000
,它也将是 0。它就是 printf
默认情况下打印 0 的方式,它不会不必要地打印零。如果你在 32 位变量中有 0x70
那么它实际上是 0x00000070
但 printf
将打印 0x70
,因为不必要的零被切掉,除非你另有说明。这就是 %02x
的用武之地。在 %02x
中,02
告诉 printf
无论如何你都想显示 2 个字节,所以它会在 [ 的情况下打印两个零=25=]
printf("%02x \n",buffer_RX[i]);
如果你想打印 0x00000070
的整个 32 位(4 字节),下面一行就可以做到:
printf("%08x \n",buffer_RX[i]);
在串行通信中,我需要将密文从python发送到能够使用C读取的UART。
首先,在python端使用这个技巧:
ciphertext=(b'\x24\x70\xb4\xc5\x5a\xd8\xcd\xb7\x80\x6a\x7b\x00\x30\x69\xc4\xe0\xd8')
ser.write(ciphertext)
在C端,我把接收到的密文放在一个buffer中。我测试如果第一个字节24,数据包的开始:
if (buffer_RX[0]=='\x24')
{
for (i=1;i<=17;i++) //sizeof(buffer_RX)==17
{
printf("%x \n",buffer_RX[i]);
}
}
else {
printf("It is not a packet!");
}
我得到的结果是:
70
b4
c5
5a
d8
cd
b7
80
6a
7b
0
30
69
c4
e0
d8
所以我有两个问题,
- 拳头是为什么 \x00
以这种方式显示,我的意思是只有一个零 0?
- 第二个是我怎么能有同样的表示:
const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};
如果我认为这是字节之间的连接,我的意思是可能是:
unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];
但我不确定,我认为我有语法错误。
此表示将帮助我继续下一步。但是我不知道怎么才能得到它。
如果您想从 1 字节块创建 4 字节长的数据。
const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};
仅对字节进行或操作是不够的,您必须将它们移动到正确的位置。
你目前在做什么,(注意你已经过度索引 plaintext[1]
这应该是 plaintext[0]
):
unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];
在内存中有这个结果,假设int
是32位,4字节长:
--------------------------------------------------------------------------------
| 3. byte | 2. byte | 1. byte | 0. byte |
--------------------------------------------------------------------------------
| 0x00 | 0x00 | 0x00 | buffer_RX[3] | buffer_RX[4] | buffer_RX[5] |
--------------------------------------------------------------------------------
因此您必须首先使用左移运算符将适当的字节移动到正确的位置 <<
,然后对之后的字节进行或运算。
这是一个例子:
#include <stdio.h>
int main()
{
unsigned char buffer_RX[4];
buffer_RX[0] = 0x70;
buffer_RX[1] = 0xb4;
buffer_RX[2] = 0xc5;
buffer_RX[3] = 0x5a;
unsigned int plaintext[1];
plaintext[0] = (buffer_RX[0]<<24) | (buffer_RX[1]<<16) | (buffer_RX[2]<<8) | buffer_RX[3];
printf("plaintext: %08x\n", plaintext[0]);
return 0;
}
输出:
记忆中:
----------------------------------------------------------------------
| 3. byte | 2. byte | 1. byte | 0. byte |
----------------------------------------------------------------------
| buffer_RX[0] | buffer_RX[1] | buffer_RX[2] | buffer_RX[3] |
----------------------------------------------------------------------
你可以看到 buffer_RX[0]
已经移动了 24 ,这是 3 个字节,所以它跳过前三个单元格,跳到最后一个。
buffer_RX[1]
by 16 这是 2 个字节,所以它跳到前两个,buffer_RX[2]
by 8 这是 1 个字节,所以它跳过第一个。并且 buffer_RX[3]
没有移动,因为它转到了第一位。
关于0x00
,它在8位上表示为零。如果您打印它,那将只是 0。如果您打印 0x0000
,它也将是 0。它就是 printf
默认情况下打印 0 的方式,它不会不必要地打印零。如果你在 32 位变量中有 0x70
那么它实际上是 0x00000070
但 printf
将打印 0x70
,因为不必要的零被切掉,除非你另有说明。这就是 %02x
的用武之地。在 %02x
中,02
告诉 printf
无论如何你都想显示 2 个字节,所以它会在 [ 的情况下打印两个零=25=]
printf("%02x \n",buffer_RX[i]);
如果你想打印 0x00000070
的整个 32 位(4 字节),下面一行就可以做到:
printf("%08x \n",buffer_RX[i]);