从几个余数中恢复一个数(中国余数定理)
我有一个长整数,但它不是以十进制形式存储,而是作为余数集存储。
所以,我没有 N
数字,而是一组这样的余数:
r_1 = N % 2147483743
r_2 = N % 2147483713
r_3 = N % 2147483693
r_4 = N % 2147483659
r_5 = N % 2147483647
r_6 = N % 2147483629
我知道,N 小于这些素数的乘积,所以中国余数定理在这里确实有效( http://en.wikipedia.org/wiki/Chinese_remainder_theorem )。
如果我有这 6 个余数,我怎样才能以十进制恢复 N
? 任何程序都可以做到这一点(C/C+GMP/C++/perl/java /公元前)。
例如,最小 N 可以得到这组余数:
r_1 = 1246736738 (% 2147483743)
r_2 = 748761 (% 2147483713)
r_3 = 1829651881 (% 2147483693)
r_4 = 2008266397 (% 2147483659)
r_5 = 748030137 (% 2147483647)
r_6 = 1460049539 (% 2147483629)
I have a long integer number, but it is stored not in decimal form, but as set of remainders.
So, I have not the N
number, but set of such remainders:
r_1 = N % 2147483743
r_2 = N % 2147483713
r_3 = N % 2147483693
r_4 = N % 2147483659
r_5 = N % 2147483647
r_6 = N % 2147483629
I know, that N is less than multiplication of these primes, so chinese remainder theorem does work here ( http://en.wikipedia.org/wiki/Chinese_remainder_theorem ).
How can I restore N
in decimal, if I have this 6 remainders? The wonderful will be any program to do this (C/C+GMP/C++/perl/java/bc).
For example, what minimal N can have this set of remainders:
r_1 = 1246736738 (% 2147483743)
r_2 = 748761 (% 2147483713)
r_3 = 1829651881 (% 2147483693)
r_4 = 2008266397 (% 2147483659)
r_5 = 748030137 (% 2147483647)
r_6 = 1460049539 (% 2147483629)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您链接的文章已经提供了寻找解决方案的建设性算法。
基本上,对于每个
i
,您求解整数方程ri*ni + si*(N/ni) = 1
,其中N = n1*n2*n3*.. .
。ri
和si
在这里是未知的。这可以通过扩展欧几里德算法来解决。它非常流行,您可以毫无问题地找到任何语言的示例实现。然后,假设
ei = si*(N/ni)
,则每个i
的答案是sum(ei*ai)
。所有这些都在那篇文章中进行了描述,并附有证据和示例。
The article you link already provides a constructive algorithm to find the solution.
Basically, for each
i
you solve integer equationri*ni + si*(N/ni) = 1
whereN = n1*n2*n3*...
. Theri
andsi
are unknowns here. This can be solved by extended euclidean algorithm. It's very popular and you'll have no problem finding sample implementations in any language.Then, assuming
ei = si*(N/ni)
, the answer issum(ei*ai)
for everyi
.All this is described in that article, with proof and example.
这里是代码 (C+GMP),基于 Ben Lynn blynn@github 的 LGPL 代码; stanford 的 Garner 算法(通过 RIP Google Code Search 通过查询 garner mpz_t 找到):
https://github.com/blynn/pbc/blob/master/guru /indexcalculus.c
(他的 PBC(基于配对的加密)库的一部分)
使用
gcc -std=c99 -lgmp
进行编译。还要根据您的情况更改尺寸。示例已解决:
N 为 703066055325632897509116263399480311
Here the code (C+GMP), based on this LGPL code by Ben Lynn blynn@github; stanford of Garner algorithm (found with RIP Google Code Search by query garner mpz_t):
https://github.com/blynn/pbc/blob/master/guru/indexcalculus.c
(Part of his The PBC (Pairing-Based Crypto) library)
Compile with
gcc -std=c99 -lgmp
. Also change size for your case.Example is solved:
N is 703066055325632897509116263399480311
以下是基于此 Rosetta Code 任务的 Python 3 实现:https://rosettacode.org/wiki/Chinese_remainder_theorem
Python 的一个很好的特性是它天然支持任意大的整数。
Here's a Python 3 implementation, based on this Rosetta Code task: https://rosettacode.org/wiki/Chinese_remainder_theorem
A nice feature of Python is that it supports arbitrarily large integers naturally.
只需添加此处的一点理论及其逐字实现
python
:另一种可能性是使用 加纳算法。
Just adding a little bit of theory from here and its verbatim implementation with
python
:Another possibility is to use the Garner's algorithm.