【问题标题】:Inverse unsigned char in PythonPython中的反无符号字符
【发布时间】:2017-08-05 12:38:35
【问题描述】:

我有 C++ 代码:

unsigned char LRC_form(char* cadr)
{
  unsigned char LRC=0;
  unsigned int t=0;
  LRC=0;
  for (t=1;t<0x0D;t=t+2)
  {
    LRC=LRC+ASCII2hex(cadr[t])*16+ASCII2hex(cadr[t+1]);
  }
  return ((~(LRC))+1);
}
int main(int argc, char *argv[])
{
    char *p={":010600000045"};
    cout<<LRC_form(p);
}

其中 ASCII2Hex 是将字符的 ASCII 代码转换为 HEX 的函数。 我必须用 Python 写同样的东西,所以我这样做:

def LRC_FORM():
    LRC=0
    string_to_send = "010600000045"
    Arr = list(string_to_send)
    #LRC = int(Arr[1])+2
    #print(LRC)
    counter=0
    for i in string_to_send:
        numb = int(i, 16)
        if counter%2 == 0:
            LRC = LRC + numb * 16
        else:
            LRC = LRC + numb
        counter = counter + 1

但是我应该如何实现 (~LRC) + 1,因为 LRC 是一个无符号字符,在我的情况下它是 int,我可以使用一些模块,如 ctypes 或 struct,但是当我这样做时:

import ctypes
import struct
cchar1=(struct.pack('1B',LRC)) 
cchar2= ctypes.c_char(LRC) 

它没有给我我期望的结果。 LRC = 77,虽然我应该得到LRC = '77',但我得到的是b'L',所以它不会像C++中的代码那样给出相同的结果。 我怎样才能以正确的方式转换它?

提前谢谢你!

附: C++程序的输出

char *p={":010600000045"};
cout<<LRC_form(p);

76 我正在尝试使用 Python 3 获得相同的效果

编辑 1

return LRC; 

在 C 程序中给出76。 我可以在我的 Python 代码中得到相同的结果。 但是

return ((~(LRC))+1);

给出180,我不知道我应该怎么做才能在 Python 中得到同样的结果..

编辑 2

ASCII2Hex 函数:

unsigned char ASCII2hex (char ASCII)
{
  if (ASCII<0x40)
    return (ASCII-0x30);
  else
    return (ASCII-0x37);
}
    enter code here

【问题讨论】:

  • 我已经编辑了您的问题,因为您的代码是 C++,而不是 C。
  • 你很接近:b'L'[0] == 76。但是在 Python 中有更紧凑的方法可以做到这一点。
  • 谢谢!我不明白..所以 L 应该是一个数组..?能否请您展示在 Python 中实现它的更紧凑的方法?
  • ASCII2hex 到底是做什么的?
  • b'L' 是文字 bytes 字符串。这有点好笑,因为它看起来 像一个字符串,但是如果你遍历它,或者索引其中的单个字节,你会得到整数值。在解释器中试试这个:for i in b'ABCD': print(i)

标签: python c++ unsigned-char


【解决方案1】:

执行此操作的简单方法是让binascii.unhexlify 完成大部分工作。我们只需要发送一个bytes 字符串,而不是文本字符串。

import binascii

def lrc(s):
    # Convert string s to bytes
    b = s.encode('ascii')

    # Interpret hex data in b
    h = binascii.unhexlify(b)

    # Add the byte values
    return sum(h)

# test

s = "010600000045"
print(lrc(s))

输出

76

我们可以使这个函数更加紧凑,尽管结果可读性较差:

def lrc(s):
    return sum(binascii.unhexlify(s.encode('ascii')))

我们可以很容易地在 Python 中执行((~(LRC))+1),但我们必须小心,原因有两个。首先,Python 没有无符号整数,其次,Python 的整数具有无限精度。但是我们可以通过提供合适的面罩来处理这两件事。如果我们想将结果限制为 8 位,我们可以使用 0xff == 255 的掩码:

l = 76
print(l, (0xff & ~l) + 1)

输出

76 180

或者我们可以在反转位之后但在我们进行掩码之前进行加法:

0xff & (~l + 1)

【讨论】:

  • 谢谢,如何得到180,是通过return ((~(LRC))+1);完成的;
  • (~76 + 1) &amp; 0xFF -> 180
  • 对于第一个代码 sn-p,在 Python 2 中得到了错误,TypeError: unsupported operand type(s) for +: 'int' and 'str
  • @xxx--- 抱歉,此答案适用于 Python 3。对于 Python 2,您需要稍微不同的方法,因为 Python 2 没有明确区分文本和字节。
【解决方案2】:

你可以简单地用 0xff 将结果强制返回到 unsigned char 范围内:

return ((~LRC)+1) & 0xff

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    相关资源
    最近更新 更多