| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 31036 人关注过本帖
标题:各位老师好!求助编辑一个大整数的快速乘除法可调用程序
取消只看楼主 加入收藏
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
重发一下欧拉定理的证明,是网上摘录复制过来的:(帮助理解或参考了解一下)
数论定理
内容
在数论中,欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。欧拉定理表明,若n,a为正整数,且n,a互质,则:
a^[φ(n)]≡1 (mod n)
证明
将1~n中与n互质的数按顺序排布:x1,x2……xφ(n) (显然,共有φ(n)个数)
我们考虑这么一些数:
m1=a*x1;m2=a*x2;m3=a*x3……mφ(n)=a*xφ(n)
1)这些数中的任意两个都不模n同余,因为如果有mS≡mR (mod n) (这里假定mS更大一些),就有:
mS-mR=a(xS-xR)=qn,即n能整除a(xS-xR)。但是a与n互质,a与n的最大公因子是1,而xS-xR<n,因而左式不可能被n整除。也就是说这些数中的任意两个都不模n同余,φ(n)个数有φ(n)种余数。
2)这些数除n的余数都与n互质,因为如果余数与n有公因子r,那么a*xi=pn+qr=r(……),a*xi与n不互质,而这是不可能的。(因为a*xi=pn+qr=r(……),说明a*xi含有因子r,又因为前面假设n含有因子r,所以a*xi和n含有公因子r,因此a*xi与n不互质)那么这些数除n的余数,都在x1,x2,x3……xφ(n)中,因为这是1~n中与n互质的所有数,而余数又小于n.
由1)和2)可知,数m1,m2,m3……mφ(n)(如果将其次序重新排列)必须相应地同余于x1,x2,x3……xφ(n).
故得出:m1*m2*m3……mφ(n)≡x1*x2*x3……xφ(n) (mod n)
或者说a^[φ(n)]*(x1*x2*x3……xφ(n))≡x1*x2*x3……xφ(n)(mod n)
或者为了方便:K{a^[φ(n)]-1}≡0 ( mod n ) 这里K=x1*x2*x3……xφ(n)。
可知K{a^[φ(n)]-1}被n整除。但K中的因子x1,x2……都与n互质,所以K与n互质。那么a^[φ(n)]-1必须能被n整除,即a^[φ(n)]-1≡0 (mod n),即a^[φ(n)]≡1 (mod n),得证。
费马小定理:
a是不能被质数p整除的正整数,则有a^(p-1) ≡ 1 (mod p)
证明这个定理非常简单,由于p是质数,所以有φ(p) = p-1,代入欧拉定理即可证明。推论:对于任意正整数a,有a^p ≡ a (mod p),因为a能被p整除时结论显然成立。

[此贴子已经被作者于2020-3-3 22:56编辑过]

2020-03-03 22:53
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
  等式m^(ed)=m(mod n)可以用欧拉定理的推论简单证明的,证明如下:
证明:根据欧拉定理的推论,
若正整数a,n互质,那么对于任意正整数b,有a^b≡a^(b mod φ(n))(mod n)。
令b=ed,则m^(ed)=m^b,由于ed=1(mod  φ(n)),所以m^(b mod φ(n))=m (mod n)。
证毕!
2020-03-04 11:06
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 197楼 wmf2014
谢谢您!fft我也至今不会,能提高速度就好!
2020-03-04 16:14
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
下面的vc程序朋友给了注释,看懂的老师请给翻译成为vb程序:

//下面是网上找到的用vc编程的fft快速高精度乘法程序,我看不懂,请看看,翻译成vb可调用程序,谢谢!
//cp可定义变量为复数
#include<bits/stdc++.h>
using namespace std;
//complex是stl自带的定义复数的容器
typedef complex<double> cp;
#define N 2097153
//定义pie=表示圆周率π 这个常数
const double pie=acos(-1);
int n;
//定义n为(?)数
cp a[N],b[N];
//定义a[N],b[N]为复数
int rev[N],ans[N];
char s1[N],s2[N];
//读入优化
//定义 rev[N],ans[N]为整数数组
//定义s1[N],s2[N]为字符数组
int read(){ //函数
    int sum=0,f=1; //定义为整数并赋初值
    char ch=getchar();//屏幕输入一个字符
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
//如果ch为“-”让f=-1,ch=getchar(),屏幕输入一个字符
//循环保证读到的字符为数字
    while(ch>='0'&&ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
//如果字符为数值执行以下
//“sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar()”输入数字(?看不清是啥字)
    return sum*f;
}  //读入一个带正负号的整数(合?看不清啥字)
//初始化每个位置最终到达的位置
{
    int len=1<<k; //定义len为整数并赋值len=2^k,朋友给出的注释,发的手工写的图片后面还多不清楚不发了。
    for(int i=0;i<len;i++)
    rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
//a表示要操作的系数,n表示序列长度
//若flag为1,则表示FFT,为-1则为IFFT(需要求倒数)
void fft(cp *a,int n,int flag){
    for(int i=0;i<n;i++)
    {
     //i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。
      if(i<rev[i])swap(a[i],a[rev[i]]);
    }
    for(int h=1;h<n;h*=2)//h是准备合并序列的长度的二分之一
    {
    cp wn=exp(cp(0,flag*pie/h));//求单位根w_n^1
     for(int j=0;j<n;j+=h*2)//j表示合并到了哪一位
     {
      cp w(1,0);
       for(int k=j;k<j+h;k++)//只扫左半部分,得到右半部分的答案
       {
         cp x=a[k];
         cp y=w*a[k+h];
         a[k]=x+y;  //这两步是蝴蝶变换
         a[k+h]=x-y;
         w*=wn; //求w_n^k
       }
     }
     }
     //判断是否是FFT还是IFFT
     if(flag==-1)
     for(int i=0;i<n;i++)
     a[i]/=n;
}
int main(){
    n=read();
    scanf("%s%s",s1,s2);
    //读入的数的每一位看成多项式的一项,保存在复数的实部
    for(int i=0;i<n;i++)a[i]=(double)(s1[n-i-1]-'0');
    for(int i=0;i<n;i++)b[i]=(double)(s2[n-i-1]-'0');
    //k表示转化成二进制的位数
    int k=1,s=2;
     while((1<<k)<2*n-1)k++,s<<=1;
    init(k);
    //FFT 把a的系数表示转化为点值表示
    fft(a,s,1);
    //FFT 把b的系数表示转化为点值表示
    fft(b,s,1);
    //FFT 两个多项式的点值表示相乘
    for(int i=0;i<s;i++)
    a[i]*=b[i];
    //IFFT 把这个点值表示转化为系数表示
    fft(a,s,-1);
    //保存答案的每一位(注意进位)
    for(int i=0;i<s;i++)
    {
    //取实数四舍五入,此时虚数部分应当为0或由于浮点误差接近0
    ans[i]+=(int)(a[i].real()+0.5);
    ans[i+1]+=ans[i]/10;
    ans[i]%=10;
    }
    while(!ans[s]&&s>-1)s--;
    if(s==-1)printf("0");
    else
    for(int i=s;i>=0;i--)
    printf("%d",ans[i]);
    return 0;
}
2020-03-06 14:13
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
下面是朋友发的最后3张图片:
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
2020-03-06 14:19
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
M521=6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151(共157位)是第13个梅森素数。M607=531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127(共有183位)是第14个梅森素数

快速乘法除法程序不仅可以用于快速分解大整数,还可以用于判断梅森素数,分解梅森合数,梅森素数的判断用到卢卡斯-莱模法,上面的判断就是用此法,由于我的程序速度慢效率低,就这么小的数程序运行时间长,无法忍受,再大的程序就算不出来死机了一样。这样的程序很有价值我感觉,希望老师指点!
2020-03-06 15:31
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
朋友的注释共有17张图片,我注释了4张,发了末尾3张,还有10张没有弄懂看不清楚没有发,不懂原理,通过末尾3张注释看大致是:把乘数被乘数由多项式系数表示法变为点值表示,通过快速fft,再相乘,结果变为系数表示法,用快速逆fft变换。不懂vc语句,有懂的感兴趣的老师朋友,请给与指导,谢谢!
2020-03-07 18:41
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
2^101-1=2535301200456458802993406410751=7432339208719*341117531003194129,
这么大的梅森数,如下网站可以分解:WolframAlpha
最大能分解多少不知道,我也没有登录,只是在网上见到了图片,图片中的例子就是前面的这个数。我的程序还没有达到这样的速度和效率,正在研究完善这样的理论和方法。
关于RSA密码的破解,据网上说已经能分解700多位的整数,所以1024或2048位的密码才是安全的。
我的分解整数的原理是特殊数域法,1024或2048位的整数理论上是应该能分解的,但由于程序速度慢效率低,根本达不到要求,只能分解几十位的且时间长,慢到无法忍受。
前面这个网站的程序就可以分解大整数,不知道能分解到多少位的?
欢迎感兴趣的沟通,欢迎指导!欢迎发表快速乘法除法程序,最好是VB版的。
咱不是黑客,不当黑客,只是为了研究整数的规律。黑客用的编程工具据说大多是汇编语言和c语言,没有用vb语言。即使能分解这么大的整数也不可能破解密码,没有黑客程序去哪里得到密码?仅是说明一下可能性,量子计算机的研制速度在提高,RSA密码体制必然面临淘汰,需要改进或重新建立新的密码体制。(秀尔算法据说可以破解RSA密码,咱不懂原理,据说其中的一个步骤必须用量子计算机,还要结合传统计算机才能破解密码)
2020-03-12 14:35
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
下面是计算和判断梅森数的程序,仅发主程序供大家参考,希望得到快速乘法除法程序以提高这个程序的速度:(判断法采用卢卡斯-莱莫测试法)
 Private Sub Command1_Click()
Dim a
a = Val(Text1)
B = 1
Do While C <= a - 1
B = MbC(Trim(B), 2)
C = C + 1
Loop
Text2 = MPC(Trim(B), 1)
End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
Text3 = ""

End Sub
 

Private Sub Command3_Click()
Dim a
B = Trim(Text1)
B1 = 1
Do While C <= B - 1
B1 = MbC(Trim(B1), 2)
C = C + 1
Loop
a = MPC(Trim(B1), 1)

If Len(a) <= 11 Then
Text3 = fenjieyinzi(Trim(a))
Else
Text3 = fenjieyinzi1(Trim(a), Val(B))
End If
End Sub

Private Function fenjieyinzi1(sa As String, sb As String) As String
Dim X, B
X = Trim(sa)

 B = Val(sb)
 s = 4
 B1 = 0
Do While B1 <= B
If InStr(MCC1(Trim(s), Trim(X)), "/") = 0 Then
a = True
Else
a = a
End If
B1 = B1 + 1
s1 = zhengchuqyushu(MCC1(Trim(s), Trim(X)))
s2 = s2 & s1 & "(" & B1 & ")" & vbCrLf
s = MPC(MbC(Trim(s1), Trim(s1)), 2)
Loop
If a = True Then
fenjieyinzi1 = "这是素数" & s2
Else
fenjieyinzi1 = "2*2" & s2
End If

End Function
2020-03-15 16:45
ysr2857
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:34
帖 子:809
专家分:77
注 册:2020-2-10
收藏
得分:0 
回复 199楼 ysr2857
199楼的vc程序谁能直接翻译成vb程序?有朋友说不必先弄懂原理,可以直接翻译成basic程序的,只要运行没有错误就行。
2020-03-24 14:57
快速回复:各位老师好!求助编辑一个大整数的快速乘除法可调用程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.257107 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved