大质数取模 - TypeError:不支持的操作数类型:'int' 和 'str
我正在尝试将一个很大的字符串 F 分成 m 个块,方法如下:
import random
from largeprimes import generateRandom
def generateRandom(length):
t = random.randint(0, 2**length)
str = "{0:b}".format(t)
if (len(str) < length):
str.zfill(length)
return str
def divide_file_block (): #return bi: int
b = []
for i in range (0, m):
b_i = F[(i*blocklen) : ((i+1)* blocklen)]
temp = int(b_i, 2) % q
b.append(temp)
return b
F = generateRandom(102400)
m = 100
blocklen = len(F)/m
q = generateLargePrime(1024) # generateLargePrime is from https://langui.sh/2009/03/07/generating-very-large-primes/
print divide_file_block ()
注意:你需要从 1 复制代码到当前目录,去掉最后的 print
语句,然后将文件命名为 largpeprimes.py
。这样就可以导入 generateLargePrime
函数了。
当我在一个小例子上测试时,结果是正确的。但是当我在 b_i 和 q 都是 1024 位的情况下测试时,出现了错误:
temp = int(b_i, 2) % q
TypeError: unsupported operand type(s) for %: 'int' and 'str'
你能帮我解释一下为什么会这样吗?并给我一些建议来解决这个问题。非常感谢!
1 个回答
2
函数 generateLargePrime
有时会返回字符串
我在尝试代码时遇到了同样的问题。
在调试器中测试时,我找到了原因:q
的值是 `'Failure after 1100.0 tries.'`。
这显然是一个字符串,导致了失败。
我建议修改 generateLargePrime
的代码,让它抛出一个异常,而不是通过返回值来报告失败。
检测这类问题的一些小技巧
打印出有问题的值
这是最简单(也可能是最常用)的快速解决方案。
像这样:
b_i = F[(i*blocklen) : ((i+1)* blocklen)]
print "q", q # here is all the magic
temp = int(b_i, 2) % q
可以告诉你具体的值。
在代码中放入 assert
b_i = F[(i*blocklen) : ((i+1)* blocklen)]
assert isinstance(q, int)
temp = int(b_i, 2) % q
当 q
不是 int
类型时,会立即抛出异常。
在调试器中运行代码
pdb
是 Python 自带的调试工具,我更喜欢 ipdb
,它是 IPython 的一部分,这两者都能帮助你。
- 把出错的代码写成一个脚本。
尝试通过 Python 解释器运行它。
$ python failingscript.py
当它出错时,你可以再试一次,但这次用
pdb
或ipdb
。$ ipdb failingscript.py
调试器让你逐行控制代码的运行。通常我会用 "c"(继续)命令让它运行,直到在出错的地方崩溃。然后我用 "l"(列出)查看当前代码行,最后用 "p"(打印)命令打印出导致问题的变量值。这样我用 "p q" 就发现它是一个字符串。
学习 pdb
或 ipdb
需要一点时间,但它们能大大提高解决问题的效率,所以绝对值得学习。一个很好的教程在 PMotW。