简体   繁体   English

在Python(Hill Cipher)中将float转换为int

[英]Conversion of float to int in Python (Hill Cipher)

I am getting different results for conversion of float to int in my Hill Cipher code (during decryption). Hill密码中 ,将float转换为int时,我得到了不同的结果(在解密过程中)。

Code : https://github.com/krshrimali/Hill-Cipher/blob/master/hill_cipher.py 代码https : //github.com/krshrimali/Hill-Cipher/blob/master/hill_cipher.py

Issue : https://github.com/krshrimali/Hill-Cipher/issues/1 问题https : //github.com/krshrimali/Hill-Cipher/issues/1

Code : 代码

# create empty plain text string
plain_text = ""
# result is a matrix [[260. 574. 439.]]
# addition of 65 because inputs are uppercase letters
for i in range(dimensions):
    plain_text += chr(int(result[0][i]) % 26 + 65)

Output : ABS 输出 :ABS

(the cipher text - encrypted text - was POH) (密文-加密的文本-是POH)

Result Matrix : (after multiplication of inverse with cipher key matrix) 结果矩阵 :(将逆与密码密钥矩阵相乘后)

[[ 260. 574. 539.]]

After conversion to int: 转换为int后:

[260, 573, 538]

Can anyone explain why this happens and give a fix on this? 谁能解释为什么会这样,并对此进行修复? Thanks. 谢谢。

The problem is that you're using int , which truncates toward zero. 问题是您使用的是int ,它会截断为零。

Math with float values is inherently imprecise. 具有float值的数学运算本质上是不精确的。 If you don't understand why, the classic explanation is in What Every Computer Scientist Should Know About Floating-Point Numbers . 如果您不明白为什么,经典的解释是《每个计算机科学家应该知道的浮点数》 But the short version is that every conversion and every intermediate calculation gets rounded to the nearest 52-bit fraction to the actual number. 但是简短的版本是每次转换和每个中间计算都将四舍五入到与实际数字最接近的52位小数。 And that may mean that a calculation that would yield exactly 574 if performed with real numbers actually yields a number a tiny bit more or less than 574 when performed with float s. 这可能意味着,如果使用实数执行计算,则精确地产生574,而使用float s进行计算,实际上产生的数字比574略多或略少。 And if you end up with a number a tiny bit less than 574 and truncate it toward zero with int , you get 573 . 如果最后得到的数字比574小一点,并用int将其截断为零,则得到573

In this case, what you want to do is use round instead, which rounds to the nearest integer. 在这种情况下,您要使用的取round是四舍五入到最接近的整数。 As long as you can be sure that your accumulated error is never as large as 0.5, that will do what you want. 只要您可以确定累积的误差永远不会大于0.5,就可以做到您想要的。 And, as long as you don't pick ridiculously huge key values (which would be pointless, because you don't get any more security that way), you can be sure of that. 而且,只要您没有选择可笑的巨大键值(这将是毫无意义的,因为这样一来您就无法获得更多的安全性),您就可以确定。

However, there are two things worth considering here. 但是,这里有两件事值得考虑。

From a brief scan of the Hill cipher article at Wikipedia: It designed to be performed with quick pencil-and-paper operation. 摘自Wikipedia上Hill密码文章的简短扫描:它旨在通过快速的铅笔和纸操作来执行。 First, you don't need the inverse matrix, just a matrix that's inverse mod 26, which is easier to calculate, and means you stay in smaller numbers that are less likely to have this problem. 首先,您不需要逆矩阵,只需一个逆模数为26的矩阵,该矩阵就更容易计算,并且意味着您所用的数字较小,因此不太可能出现此问题。 And it means you can do all the math in integers, so the problem doesn't arise in the first place: create your matrix as an array with dtype=int , and there will be no rounding issues. 这意味着您可以用整数进行所有数学运算,因此首先不会出现问题:使用dtype=int将您的矩阵创建为数组,并且不会出现舍入问题。 And, as a bonus, if you do pick ridiculously huge key values, you'll get an error instead of incorrect results. 而且,作为奖励,如果你挑可笑的巨大的键值,你会得到不正确的结果的错误信息。 (If you want to allow such values, you'd want to store Python unlimited-size int values in a dtype=object array. But if you don't need that, it just makes things slower and more complicated.) (如果要允许这样的值,则希望将Python大小不受限制的int值存储在dtype=object数组中。但是,如果不需要它,只会使事情变得更慢,更复杂。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM