读取超大数字文件转int后,RSA解密时pow函数触发溢出错误如何解决
解决RSA解密中pow函数相关的OverflowError问题
问题重现
需要读取包含多段数字的密文文件,通过RSA公式 m = (c ^ d) % n 解密,使用以下函数时触发错误:
def Decrypt(file, n, d): with open(file, 'r') as fifi: for line in fifi.readlines(): x = int(line) # reads message file byte by byte with open("dec.txt", 'a') as wr: wr.write(chr(pow(x,d,n))) # write to file as string wr.close()
报错信息:
OverflowError: Python int too large to convert to C int
问题原因
这个错误不是pow函数导致的——Python的pow(x, d, n)原生支持大整数运算,不会出现溢出问题。真正的问题是:chr()函数只能接受范围在 0 到 0x10FFFF(即1114111)之间的整数,当RSA解密后的m值超过这个范围时,chr()会尝试将其转换为C int类型,从而触发溢出错误。
通常出现这种情况,是因为你的RSA密文是按块加密的(每个密文行对应多个字节的明文块),而不是单个字符的加密值,直接用chr()转换单个字符的逻辑不适用。
解决方案
改用int.to_bytes()方法将解密后的整数转换为字节串,适配RSA块解密的场景,同时优化文件操作效率:
def Decrypt(file, n, d): # 计算RSA块对应的字节长度(根据n的位数推导) block_byte_length = (n.bit_length() + 7) // 8 # 一次性打开输入输出文件(二进制模式避免编码问题) with open(file, 'r') as cipher_file, open("dec.txt", 'ab') as plain_file: for line in cipher_file: # 去除行尾的换行/空白字符,转换为整数 cipher_num = int(line.strip()) # RSA解密计算 plain_num = pow(cipher_num, d, n) # 将解密后的整数转换为字节串(RSA通常使用大端字节序) plain_bytes = plain_num.to_bytes(block_byte_length, byteorder='big') # 移除块前可能存在的空字节(加密时填充的补位) plain_bytes = plain_bytes.lstrip(b'\x00') # 写入明文字节 plain_file.write(plain_bytes)
关键优化点
- 块处理逻辑:用
to_bytes()替代chr(),适配多字节明文块的解密结果 - 文件操作优化:一次性打开输入输出文件,避免循环内反复打开关闭的性能损耗
- 二进制写入:使用
'ab'模式写入,避免字符串编码带来的额外问题
内容的提问来源于stack exchange,提问作者Lan
相关产品推荐
相关产品推荐

