将Java的按位运算转换为Python
我的问题很简单。我有一个用Java写的客户端程序,它里面有一个方法可以生成一个ID。我正在写Python脚本来解析和修正这个客户端程序的输出。这个客户端生成ID的方法使用了位运算来创建ID。不幸的是,虽然它声称生成的是UUID,但实际上这个ID生成器是独特的,并不是标准的UUID。
我想转换的代码是开源的,位于EMF EcoreUtil.java文件中1。如果你有时间或者想找点有趣的编程项目,欢迎你来翻译这段代码。不过我想知道在Python中如何像在C/C++和Java中那样进行位运算。
2 个回答
1
Python的维基百科上有一个关于位运算符的好页面。我对Java不太了解,但乍一看,我觉得很多运算符是一样的:
另外,你可能还想看看uuid模块。
运算符:
x << y Returns x with the bits shifted to the left by y places (and new bits on the right-hand-side are zeros). This is the same as multiplying x by 2**y.
x >> y Returns x with the bits shifted to the right by y places. This is the same as //'ing x by 2**y.
x & y Does a "bitwise and". Each bit of the output is 1 if the corresponding bit of x AND of y is 1, otherwise it's 0.
x | y Does a "bitwise or". Each bit of the output is 0 if the corresponding bit of x AND of y is 0, otherwise it's 1.
~ x Returns the complement of x - the number you get by switching each 1 for a 0 and each 0 for a 1. This is the same as -x - 1.
x ^ y Does a "bitwise exclusive or". Each bit of the output is the same as the corresponding bit in x if that bit in y is 0, and it's the complement of the bit in x if that bit in y is 1.
3
在Python中,位运算和C/Java中的一样(不过Python没有Java中的>>>
操作,因为它不需要;在Python中,符号扩展总是会进行,即使是0xFFFF_FFFF_FFFF_FFFF也可以表示为一个正整数)。
另外一个好处是,Python中的整数可以是任意大小的正数,而在Java中,处理位运算时会有符号的问题。
从链接的文件来看,值确实应该是一个UUID,只不过它是用base64编码的:
生成一个全球唯一标识符,也就是UUID。它将128位的UUID编码为base64,但不是用两个“=”字符来填充编码,而是用一个“_”字符作为前缀,以确保结果是一个有效的ID,也就是一个NCName。
在Python中有一个UUID类,还有一个base64编码模块;因此,整个标识符的处理可以用Python这样写:
import uuid
import base64
gen_id = uuid.uuid1() # generate type 1 UUID
id_bytes = gen_id.bytes # take its bytes
encoded = base64.b64encode(id_bytes, b'-_')
encoded = encoded.replace(b'=', b'') # remove the padding bytes
result = '_' + encoded.decode('ascii') # result is a string with '_' prepended.