首页
社区
课程
招聘
[求助]求已知算法的逆算法
发表于: 2010-8-14 18:22 7754

[求助]求已知算法的逆算法

2010-8-14 18:22
7754
算法为:
1,已知两数(16位)
    A=0x4CE2, B=0x6907
2,求两数的乘积(32位)
   A*B=0x4CE2*0x6907=0x1F8ACC2E
3,求低位(16位)和高位(16位)的差做结果,如果为负则加0x10001
   Y=0xCC2E-0x1F8A=0xACA4

现在如果知道B和Y,怎么求A?

多谢了!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
2
提示:穷举A
2010-8-14 19:30
0
雪    币: 107
活跃值: (404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
up版主一个。。。。。。。。
2010-8-14 20:43
0
雪    币: 2096
活跃值: (100)
能力值: (RANK:420 )
在线值:
发帖
回帖
粉丝
4
這個 A 有無窮多組解。
2010-8-14 21:05
0
雪    币: 324
活跃值: (192)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
难道此算法只能沦落到用穷举法吗?解还不唯一?
2010-8-15 09:36
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
6
取值范围就[0, 0xffff],怎么可能有无穷多
2010-8-15 12:03
0
雪    币: 2096
活跃值: (100)
能力值: (RANK:420 )
在线值:
发帖
回帖
粉丝
7
我也好奇的想知道,有無其它更好的方法。
2010-8-15 12:47
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
8
B是已知数,不限范围是什么概念?
fg换了这么邪恶的头像
2010-8-15 13:00
0
雪    币: 452
活跃值: (72)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
9
设变量X

Y=0xACA4
B=0x6907

解同余方程
Y + 0x10001 * X ≡ 0 (mod B)

解出X之后,
A = (Y + 0x10001 * X)/B

找到一个算法,可以求解同余方程
http://hi.baidu.com/find_chees/blog/item/d0461d3f566ad23770cf6cdb.html
2010-8-15 14:19
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
10
楼上慧眼啊,原来就是求解: A * B ≡ Y (mod 0x10001)
2010-8-15 16:02
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
11
g个代码测试一下:

DWORD GetGcd(DWORD a,DWORD b)
{
if (a < b)
{
DWORD temp = a;
a = b;
b = temp;
}

DWORD c = a;
DWORD d = b;
DWORD test = 0;
while((test = c % d) > 0)
{
c = d;
d = test;
}

return d;
}

DWORD GetXY(DWORD a,DWORD b,DWORD *xy)
{
BOOL isChange = FALSE;

if (a < b)
{
DWORD temp = a;
a = b;
b = temp;
isChange = TRUE;
}


DWORD k,p0=1,p1=0,q0=0,q1=1,temp;
int n = 0;
DWORD c = a;
DWORD d = b;
DWORD test = 0;
while((test = c%d) > 0)
{
n++;
k = c/d;

if (n==1)
{
p1 = k;
q1 = 1;
}
else
{
temp = p1;
p1 = p1*k+p0;
p0 = temp;

temp = q1;
q1 = q1*k+q0;
q0 = temp;
}

c = d;
d = test;
}

if (n%2 == 1)
{
p1 = 0 - p1;
}
else
{
q1 = 0 - q1;
}

if (isChange)
{
temp = p1;
p1 = q1;
q1 = temp;
}

xy[0] = q1;
xy[1] = p1;

return 0;
}

DWORD GetInv(DWORD a,DWORD m)
{
DWORD xy[2];

if(GetGcd(a,m) == 1)
{
GetXY(a,m,xy);
DWORD temp = xy[0] % m;
if(temp < 0)
{
temp += m;
}
return temp;
}
return -1;
}

int main()
{
DWORD A,B,X,Y,M;

M = 0x10001;
B = 0x6907;
Y = 0xACA4;
X = GetInv(B,M);
A = X * Y % M;
printf("\nA = 0x%04X",A);
_getch();

return 0;
}
2010-8-15 16:32
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
12
感谢欧几里得
2010-8-15 17:27
0
雪    币: 324
活跃值: (192)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
多谢了!

搞明白是求A*B≡ Y (mod 0x10001)的逆运算就有思路了。

源程序里有现成求模0x10001的乘法拟元函数,只需利用此模0x10001乘法拟元函数就行了。

假设B*C≡1 (mod 0x10001),则A≡A*B*C≡Y*C(mod 0x10001)

而求B模0x10001的乘法拟元C的原理正是楼上提到的“欧几里德算法”,顺便附上代码供大家参考。

00E92650  /$  55                  push    ebp
00E92651  |.  8BEC                mov     ebp, esp
00E92653  |.  83EC 1C             sub     esp, 1C
00E92656  |.  0FB745 08           movzx   eax, word ptr [ebp+8]
00E9265A  |.  85C0                test    eax, eax
00E9265C  |.  75 05               jnz     short 00E92663
00E9265E  |.  66:33C0             xor     ax, ax
00E92661  |.  EB 7E               jmp     short 00E926E1
00E92663  |>  C745 FC 01000100    mov     dword ptr [ebp-4], 10001
00E9266A  |.  0FB74D 08           movzx   ecx, word ptr [ebp+8]
00E9266E  |.  894D E8             mov     dword ptr [ebp-18], ecx
00E92671  |.  C745 F8 01000000    mov     dword ptr [ebp-8], 1
00E92678  |.  C745 E4 00000000    mov     dword ptr [ebp-1C], 0
00E9267F  |>  8B45 FC             /mov     eax, dword ptr [ebp-4]
00E92682  |.  99                  |cdq
00E92683  |.  F77D E8             |idiv    dword ptr [ebp-18]
00E92686  |.  8955 F0             |mov     dword ptr [ebp-10], edx
00E92689  |.  8B45 FC             |mov     eax, dword ptr [ebp-4]
00E9268C  |.  2B45 F0             |sub     eax, dword ptr [ebp-10]
00E9268F  |.  99                  |cdq
00E92690  |.  F77D E8             |idiv    dword ptr [ebp-18]
00E92693  |.  8945 F4             |mov     dword ptr [ebp-C], eax
00E92696  |.  837D F0 00          |cmp     dword ptr [ebp-10], 0
00E9269A  |.  75 14               |jnz     short 00E926B0
00E9269C  |.  837D F8 00          |cmp     dword ptr [ebp-8], 0
00E926A0  |.  7D 0C               |jge     short 00E926AE
00E926A2  |.  8B55 F8             |mov     edx, dword ptr [ebp-8]
00E926A5  |.  81C2 01000100       |add     edx, 10001
00E926AB  |.  8955 F8             |mov     dword ptr [ebp-8], edx
00E926AE  |>  EB 27               |jmp     short 00E926D7
00E926B0  |>  8B45 E8             |mov     eax, dword ptr [ebp-18]
00E926B3  |.  8945 FC             |mov     dword ptr [ebp-4], eax
00E926B6  |.  8B4D F0             |mov     ecx, dword ptr [ebp-10]
00E926B9  |.  894D E8             |mov     dword ptr [ebp-18], ecx
00E926BC  |.  8B55 F8             |mov     edx, dword ptr [ebp-8]
00E926BF  |.  8955 EC             |mov     dword ptr [ebp-14], edx
00E926C2  |.  8B45 F4             |mov     eax, dword ptr [ebp-C]
00E926C5  |.  0FAF45 F8           |imul    eax, dword ptr [ebp-8]
00E926C9  |.  8B4D E4             |mov     ecx, dword ptr [ebp-1C]
00E926CC  |.  2BC8                |sub     ecx, eax
00E926CE  |.  894D F8             |mov     dword ptr [ebp-8], ecx
00E926D1  |.  8B55 EC             |mov     edx, dword ptr [ebp-14]
00E926D4  |.  8955 E4             |mov     dword ptr [ebp-1C], edx
00E926D7  |>  837D F0 00          |cmp     dword ptr [ebp-10], 0
00E926DB  |.^ 75 A2               \jnz     short 00E9267F
00E926DD  |.  66:8B45 F8          mov     ax, word ptr [ebp-8]
00E926E1  |>  8BE5                mov     esp, ebp
00E926E3  |.  5D                  pop     ebp
00E926E4  \.  C3                  retn
2010-8-16 09:43
0
游客
登录 | 注册 方可回帖
返回
//