一个无符号常量 S = 0x2225CB63
一个大数常量 M = 0x95D9F4F67E40AD36482F82610093DDB1D1A98A65CB79AA26D5977A471917A9BAFB6C2E5C8127AEE103EA31D94C677BAA72638838A7339750683E4548CB51C1EB8F744D5E90173A56E0E85ED403FAC93FD2F13B0808076E26F3A01D24E6F04600AAF8F1EF4754B83DB35899B5DD1B92DECCCF732E6B86CB55FC2E01F2E722EFB27891F12E810A0C259C489121D63AB3903FCB71BD51C56A9DB0F57BD1E9512899CC3988796E5BAE816DA8871FE98A0175B23957CF5B2894B5A3D7D1A0B3A6A772A5F3CB1E8ECD0E1D99A0A7BA8EDC54740641D00D9EE18B657E19963B564B5DDCF25328AA5BA34A11B9B8D83F4DD882B97EB3ADD7A09F2EF19C2EE39B744A5D69
注册码也是一个大数,记为X
计算中使用一个大数变量,记为A
对 S 次高有效位开始,逐位扫描,进行循环。
S 的最高有效位为BIT29(最低位从BIT0算起),所以有以下循环,从BIT28开始扫描
for ( A = X, int i = 27 ; i >= 0; --i ) // A初始赋值为X
{
A = ( A * A ) % M;
if ( ( S & ( 1 << i ) ) != 0 ) // 如果当前S当前被扫描的位为1
{
A = ( A * X ) % M;
}
关于由机器码反推注册码的问题,我觉得LZ可能理解错了,我重新表述一遍吧:
问题可以形式化描述为:
已知次幂S、同余值A和模数M,解高次同余方程 X^S = A mod M 即可求出底X。
具体解法如下:
1、解同余方程 S*d = 1 mod M,即可求出d。这可以直接利用afanty提供的小程序做到;
2、按照LZ提供的算法求出A^d mod M;
3、在原方程 X^S = A mod M 两边同时取d次幂,可以作如下推导:
(X^S)^d = A^d mod M
即 X^(S*d) = A^d mod M
因为 S*d = 1 mod M,故有
X = A^d mod M
现在进行修正后给出正确答案:
问题描述:
已知次幂S、同余值A和模数M,
解同余方程 X^S = A mod M 即求底X。
具体解法:
1、解同余方程 S*d = 1 mod Ф(M),即可求出d。这里Ф表示欧拉函数;
2、按照LZ提供的算法求出A^d mod M;
3、在原方程 X^S = A mod M 两边同时取d次幂,可以作如下推导:
(X^S)^d = A^d mod M
即 X^(S*d) = A^d mod M
因为 S*d = 1 mod Ф(M),
根据欧拉定理,可得
X = X^(S*d) = A^d mod M
而在第2步中已求出 A^d mod M,故X即得。