如何从字符串python更改1位?

如何从字符串python更改1位?,python,python-2.7,random,bit-manipulation,Python,Python 2.7,Random,Bit Manipulation,我使用os.uradom(8)生成一个64位随机字符串。接下来,我想随机更改字符串的一位的值,首先得到要更改的位x=random.getrandbits(6),然后像这样对该位执行异或操作rand\u string^=1我看不到获得随机位和lshift的意义。兰丁应该做得很好。此外,如果要更改单个位,请尝试对字符而不是字符串进行异或运算。如果这不起作用,…=chr(ord(char)^x)我想你的问题中可能有输入错误。正如Jonas Wielicki所说,os.random并不存在;大概你的意思

我使用
os.uradom(8)
生成一个64位随机字符串。接下来,我想随机更改字符串的一位的值,首先得到要更改的位
x=random.getrandbits(6)
,然后像这样对该位执行异或操作
rand\u string^=1我看不到获得随机位和lshift的意义。兰丁应该做得很好。此外,如果要更改单个位,请尝试对字符而不是字符串进行异或运算。如果这不起作用,
…=chr(ord(char)^x)

我想你的问题中可能有输入错误。正如Jonas Wielicki所说,
os.random
并不存在;大概你的意思是
os.uradom
。是的,使用系统的随机源进行加密工作是个好主意,但是直接使用
os.uradom
并不方便。幸运的是,
random
模块提供了一个到
os.uradom
的接口:
SystemRandom

在Python中进行多字节对象的位旋转是可能的,尽管这有点繁琐(尤其是在Python 2中)。用Python整数做这类事情要容易得多。当然,您可以使用
getrandbits
方法获得64个随机位,尽管其中一些前导位可能是零位

下面是一些在Python2或Python3上运行的代码,这些代码生成一个随机的64位数字,翻转其中一位,然后计算原始数字与翻转位(当然是1)之间的汉明距离

有更快的方法来计算Python整数中的1位数,但是
bincount
相当快(并且比Kernighan著名算法的Python实现更快);有关其他方法,请参阅

如果需要将
bits0
转换为Python 3中易于实现的字节对象:只需使用
.to_bytes
方法,例如

bytes0 = bits0.to_bytes(8, 'big')    
如果需要使用Python2,那么将整数转换为字符串并将字符串转换为整数需要更多的工作。下面是一个演示,使用上述代码的修改版本

from __future__ import print_function
import random
from binascii import hexlify

# SystemRandom uses os.urandom() 
sysrandom = random.SystemRandom()

def bincount(n):
    return bin(n).count("1")

def int_to_bytes(n, size):
    result = []
    for _ in range(size):
        result.append(chr(n & 0xff))
        n >>= 8
    return ''.join(result[::-1])

def bytes_to_int(bs):
    n = 0
    for b in bs:
        n = (n << 8) | ord(b)
    return n

for _ in range(4):
    bits0 = sysrandom.getrandbits(64)
    print('bits0: {0:016x}'.format(bits0))

    bs = int_to_bytes(bits0, 8)
    print('bytes:', repr(bs))
    print('hex:  ', hexlify(bs))

    n = bytes_to_int(bs)
    print('int:   {0:016x}, {1}\n'.format(n, n == bits0))

首先,这是两个不同的问题。第二,我在python2或python3上都没有
os.random
,您似乎有一个打字错误。第三,你是用蟒蛇2还是蟒蛇3?(第四,您可以自己测试hamming_距离部分;只需创建两个字符串对:一对差异在同一个字符中,但两个不同的位,一对差异在两个字符中,观察输出)@JonasWielicki是的,有一个拼写错误,我指的是os.uradom()。我正在使用python2,实际上我无法测试hamming算法,因为我无法按照我想要的方式修改字符串(更改1位)。我知道它适用于列表项或字符串。例如,“abcd”和“abcc”给出了汉明距离1,但在二进制中,距离更大,因为c和d表示有一点以上的不同。谢谢你的回答,它确实帮助了我很多,但我仍然有加密函数调用的问题,因为它需要纯文本参数(问题解决了,因为虽然to_bytes()在python2.7上不起作用,但我发现了一个类似的函数-)并返回一个字符串,我应该将其转换为字节字符串,以便执行XOR,但
bytes1=to_bytes(encryptedString,8,“big”)
给了我以下错误
类型错误:%x格式:数字是必需的,而不是str
@arkan\u 18我在我的答案中添加了一些Python 2代码,可以进行int->bytes and bytes->int转换。@PM\u 2Ring谢谢!最后一个问题…如果这行给了我false,那意味着什么呢?
n==bits0
@arkan\u 18
n==bits0
永远不要出错。我只是把它放在那里,以便更容易看到
字节到int
给出了正确的结果。好吧,这在加密领域是有意义的
bits0: a508c77693a0e7d7
bitnum: 32
bits1: a508c77793a0e7d7
Hamming distance: 1

bits0: 9608e25db458a350
bitnum: 3
bits1: 9608e25db458a358
Hamming distance: 1

bits0: f485bd53af91e2dc
bitnum: 62
bits1: b485bd53af91e2dc
Hamming distance: 1

bits0: 18f6749bc260fcd1
bitnum: 17
bits1: 18f6749bc262fcd1
Hamming distance: 1

bits0: 51b35142c99b6814
bitnum: 54
bits1: 51f35142c99b6814
Hamming distance: 1
bytes0 = bits0.to_bytes(8, 'big')    
from __future__ import print_function
import random
from binascii import hexlify

# SystemRandom uses os.urandom() 
sysrandom = random.SystemRandom()

def bincount(n):
    return bin(n).count("1")

def int_to_bytes(n, size):
    result = []
    for _ in range(size):
        result.append(chr(n & 0xff))
        n >>= 8
    return ''.join(result[::-1])

def bytes_to_int(bs):
    n = 0
    for b in bs:
        n = (n << 8) | ord(b)
    return n

for _ in range(4):
    bits0 = sysrandom.getrandbits(64)
    print('bits0: {0:016x}'.format(bits0))

    bs = int_to_bytes(bits0, 8)
    print('bytes:', repr(bs))
    print('hex:  ', hexlify(bs))

    n = bytes_to_int(bs)
    print('int:   {0:016x}, {1}\n'.format(n, n == bits0))
bits0: 69831968a1b0aff8
bytes: 'i\x83\x19h\xa1\xb0\xaf\xf8'
hex:   69831968a1b0aff8
int:   69831968a1b0aff8, True

bits0: c2c77e02969d3ebc
bytes: '\xc2\xc7~\x02\x96\x9d>\xbc'
hex:   c2c77e02969d3ebc
int:   c2c77e02969d3ebc, True

bits0: e87c78eb3929a76f
bytes: '\xe8|x\xeb9)\xa7o'
hex:   e87c78eb3929a76f
int:   e87c78eb3929a76f, True

bits0: 0d5d796c986ba329
bytes: '\r]yl\x98k\xa3)'
hex:   0d5d796c986ba329
int:   0d5d796c986ba329, True