网易首页 > 网易号 > 正文 申请入驻

2023-12-02:用go语言,如何求模立方根? x^3=a mod p, p是大于

0
分享至

2023-12-02:用go语言,如何求模立方根?

x^3=a mod p,

p是大于等于3的大质数,

a是1到p-1范围的整数常数,

x也是1到p-1范围的整数,求x。

p过大,x不能从1到p-1遍历。

答案2023-12-02:

灵捷3.5

大体步骤如下:

1.判断是否存在模立方根。有0,1,3个根这三种情况。

1.1.求p-1和3的最大公约数gcd(p-1,3)。最后结果要么是1,要么是3。如果是1,那肯定模立方根,但只有1个根。如果是3,进行下一步。

1.2.欧拉判别法。a**[(p-1)/3]==1 mod p。如果等于1,那就有3个根。如果不等于1,那就是0个根。

2.Peralta算法。求y。

2.1.当只有0个根时,直接返回。

2.2.当只有1个根时,a ^ ((p-1)/3) mod p就是答案。

2.3.当有3个根时,这个很难描述,具体见代码。

2.3.1.定义复数乘法和复数的快速幂。这虽然叫复数,但跟传统意义上的复数是不一样的。

2.3.2.确定一个常数r(r>=1并且r

2.3.3.确定一个复数根,对这个复数根作复数的快速幂运算,指数是(p^2+p+1)/3,最终结果就是需要的根。

时间复杂度为 O((log p)^3)。

额外空间复杂度为 O(1)。

go完整代码如下:

packagemain
import(
"fmt"
"math/big"
)
funcmain(){
iftrue{
iffalse{
p:=big.NewInt(0)
p.SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",16)
forc:=big.NewInt(20000);c.Cmp(big.NewInt(30000))<=0;c.Add(c,big.NewInt(1)){
fmt.Println("c=",c,"-------------")
r:=ModCbrt(c,p)
fmt.Println("答案:",r)
fori:=0;iifbig.NewInt(0).Exp(r[i],big.NewInt(3),p).Cmp(c)==0{
}else{
fmt.Println("答案错误",r[i],",c=",big.NewInt(0).Exp(r[i],big.NewInt(3),p))
return
}
}
}
return
}
iftrue{
p:=big.NewInt(0)
p.SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",16)
forc:=big.NewInt(20000);c.Cmp(big.NewInt(30000))<=0;c.Add(c,big.NewInt(1)){
fmt.Println("c=",c,"-------------")
r:=ModCbrt(c,p)
fmt.Println("答案:",r)
fori:=0;iifbig.NewInt(0).Exp(r[i],big.NewInt(3),p).Cmp(c)==0{
}else{
fmt.Println("答案错误",r[i],",c=",big.NewInt(0).Exp(r[i],big.NewInt(3),p))
return
}
}
}
return
}
iftrue{
p:=big.NewInt(997)
forc:=big.NewInt(1);c.Cmp(big.NewInt(0).Add(p,big.NewInt(-1)))<=0;c.Add(c,big.NewInt(1)){
fmt.Println("c=",c,"-------------")
r:=ModCbrt(c,p)
fmt.Println("答案:",r)
fori:=0;iifbig.NewInt(0).Exp(r[i],big.NewInt(3),p).Cmp(c)==0{
}else{
fmt.Println("答案错误",r[i],",c=",big.NewInt(0).Exp(r[i],big.NewInt(3),p))
return
}
}
}
}
return
}
fmt.Println("")
}
//求模立方根的个数0,1,3
funcModCbrtCount(c,p*big.Int)int{
t:=big.NewInt(0)
t.Add(p,big.NewInt(-2))
t.Mod(t,big.NewInt(3))
ift.Cmp(big.NewInt(0))==0{
return1
}
t=big.NewInt(0).Add(p,big.NewInt(-1))
t.Div(t,big.NewInt(3))
ifbig.NewInt(0).Exp(c,t,p).Cmp(big.NewInt(1))==0{
return3
}else{
return0
}
}
//PeraltaMethod
funcModCbrt(a,p*big.Int)(ans[]*big.Int){
ans=make([]*big.Int,0)
count:=ModCbrtCount(a,p)
ifcount==1{//有1个解
t:=big.NewInt(0).Lsh(p,1)
t.Mod(t,p)
t=t.Add(t,big.NewInt(-1))
t.Mod(t,p)
t.Mul(t,big.NewInt(0).ModInverse(big.NewInt(3),p))
t.Mod(t,p)
ans=append(ans,big.NewInt(0).Exp(a,t,p))
}elseifcount==3{//有3个解,PeraltaMethod算法
w:=big.NewInt(0)
p3:=big.NewInt(0).Add(p,big.NewInt(-1))//(p-1)/3
p3.Mul(p3,big.NewInt(0).ModInverse(big.NewInt(3),p))
p3.Mod(p3,p)
fori:=big.NewInt(1);i.Cmp(p)<0;i.Add(i,big.NewInt(1)){
w.Exp(i,p3,p)
ifw.Cmp(big.NewInt(1))!=0{
break
}
}
varx*big.Int
key:=big.NewInt(0)
forx=big.NewInt(1);x.Cmp(p)<0;x.Add(x,big.NewInt(1)){
key.Exp(x,big.NewInt(3),p)//key=x^3-a
key.Add(key,big.NewInt(0).Neg(a))
key.Mod(key,p)
ifkey.Cmp(big.NewInt(0))!=0&&ModCbrtCount(key,p)==0{
break
}
}
r:=Ring{x,big.NewInt(0).Add(p,big.NewInt(-1)),big.NewInt(0),key}
pp:=big.NewInt(0).Mul(p,p)//pp=(p*p+p+1)/3,注意pp是不能modp的,有点反直觉
pp.Add(pp,p)
pp.Add(pp,big.NewInt(1))
pp.Div(pp,big.NewInt(3))
ansr:=powerModI(r,pp,p)
ans0:=ansr.a
ans1:=big.NewInt(0)
ans1.Mul(ans0,w)
ans1.Mod(ans1,p)
ans2:=big.NewInt(0)
ans2.Mul(ans1,w)
ans2.Mod(ans2,p)
ans=append(ans,ans0,ans1,ans2)
}
return
}
typeRingstruct{
a*big.Int
b*big.Int
c*big.Int
w*big.Int
}
//复数乘法
funcmulI(xRing,yRing,p*big.Int)Ring{
varresRing
res.a=big.NewInt(0)
res.b=big.NewInt(0)
res.c=big.NewInt(0)
res.w=x.w
w:=x.w
a1:=big.NewInt(0)
a2:=big.NewInt(0)
a3:=big.NewInt(0)
a1.Mul(x.a,y.a)//x.a*y.a
a1.Mod(a1,p)
a2.Mul(x.b,y.c)//x.b*y.c*key
a2.Mod(a2,p)
a2.Mul(a2,w)
a2.Mod(a2,p)
a3.Mul(x.c,y.b)//x.c*y.b*key
a3.Mod(a3,p)
a3.Mul(a3,w)
a3.Mod(a3,p)
res.a.Add(a1,a2)
res.a.Mod(res.a,p)
res.a.Add(res.a,a3)
res.a.Mod(res.a,p)
b1:=big.NewInt(0)
b2:=big.NewInt(0)
b3:=big.NewInt(0)
b1.Mul(x.a,y.b)//x.a*y.b
b1.Mod(b1,p)
b2.Mul(x.b,y.a)//x.b*y.a
b2.Mod(b2,p)
b3.Mul(x.c,y.c)//x.c*y.c*key
b3.Mod(b3,p)
b3.Mul(b3,w)
b3.Mod(b3,p)
res.b.Add(b1,b2)
res.b.Mod(res.b,p)
res.b.Add(res.b,b3)
res.b.Mod(res.b,p)
c1:=big.NewInt(0)
c2:=big.NewInt(0)
c3:=big.NewInt(0)
c1.Mul(x.a,y.c)//x.a*y.c
c1.Mod(c1,p)
c2.Mul(x.b,y.b)//x.b*y.b
c2.Mod(c2,p)
c3.Mul(x.c,y.a)//x.c*y.a
c3.Mod(c3,p)
res.c.Add(c1,c2)
res.c.Mod(res.c,p)
res.c.Add(res.c,c3)
res.c.Mod(res.c,p)
returnres
}
//复数快速幂,注意b不能取模
funcpowerModI(aRing,b,p*big.Int)Ring{
res:=Ring{big.NewInt(1),big.NewInt(0),big.NewInt(0),a.w}
forb.Cmp(big.NewInt(0))!=0{
ifbig.NewInt(0).Mod(b,big.NewInt(2)).Cmp(big.NewInt(1))==0{
res=mulI(res,a,p)
}
a=mulI(a,a,p)
b.Rsh(b,1)
}
returnres
}

声明:个人原创,仅供参考

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
大暴雨!冰雹!8级雷暴大风!首个山洪红色预警!气象部门紧急提醒→

大暴雨!冰雹!8级雷暴大风!首个山洪红色预警!气象部门紧急提醒→

鲁中晨报
2024-06-16 14:43:05
伊朗态度大变?突然召见中国大使,当面发出抗议,中方回应亮了!

伊朗态度大变?突然召见中国大使,当面发出抗议,中方回应亮了!

诉人世间
2024-06-17 00:30:02
90年代台海危机中的心酸:中国空军苏-27战斗机,吓人的花瓶

90年代台海危机中的心酸:中国空军苏-27战斗机,吓人的花瓶

慎独赢
2024-06-16 11:51:15
理想车友聚会多车连环追尾的瓜

理想车友聚会多车连环追尾的瓜

一个岛岛
2024-06-16 16:42:12
镜报:曼城老板与瓜迪奥拉会面,希望说服他与俱乐部续约

镜报:曼城老板与瓜迪奥拉会面,希望说服他与俱乐部续约

直播吧
2024-06-16 09:57:12
不打了?CBA最强外援被曝欲离队,广东男篮有望重金签下他!

不打了?CBA最强外援被曝欲离队,广东男篮有望重金签下他!

绯雨儿
2024-06-16 16:16:04
大陆男子驾艇成功登台湾细节曝光:突破5亿监控系统后,自己报警

大陆男子驾艇成功登台湾细节曝光:突破5亿监控系统后,自己报警

消失的电波
2024-06-13 10:01:58
《玫瑰的故事》那么明显的穿帮镜头,竟没有剪掉,看着真是一脸懵

《玫瑰的故事》那么明显的穿帮镜头,竟没有剪掉,看着真是一脸懵

娱乐圈笔娱君
2024-06-14 17:55:48
国家终于不再原谅王濛,77枚金牌不是万能,而自大只会被抛弃

国家终于不再原谅王濛,77枚金牌不是万能,而自大只会被抛弃

兰子记
2024-06-11 18:28:00
国足豪赌世界杯!足协锁定巴西外援 最快1月完成归化

国足豪赌世界杯!足协锁定巴西外援 最快1月完成归化

球事百科吖
2024-06-16 16:34:09
谭咏麟病愈后首次公开现身,瘦到青筋毕现感慨声线不好

谭咏麟病愈后首次公开现身,瘦到青筋毕现感慨声线不好

小萝卜天下事
2023-07-21 21:57:53
把150万给儿子,女儿一家没了音讯,10年后我们在女儿旧房前痛哭

把150万给儿子,女儿一家没了音讯,10年后我们在女儿旧房前痛哭

半夏解语
2024-06-15 07:00:03
3:0波兰,龚翔宇大哭原因曝光,李盈莹背后轻抱,低迷之人该清醒

3:0波兰,龚翔宇大哭原因曝光,李盈莹背后轻抱,低迷之人该清醒

东球弟
2024-06-16 21:45:46
拜登已签字,22国一致对华征税,中方加量囤粮食,瑞典的努力白费

拜登已签字,22国一致对华征税,中方加量囤粮食,瑞典的努力白费

影视解说阿相
2024-06-15 12:39:36
中国女排3比0波兰数据:队长袁心玥16分最高,李盈莹14分次席

中国女排3比0波兰数据:队长袁心玥16分最高,李盈莹14分次席

直播吧
2024-06-16 22:10:57
G7为何敢用冻结俄资产做担保为乌提供500亿,因为俄T-62坦克上场

G7为何敢用冻结俄资产做担保为乌提供500亿,因为俄T-62坦克上场

山河路口
2024-06-15 23:54:24
一个上市公司能无耻到什么程度呢?

一个上市公司能无耻到什么程度呢?

流苏晚晴
2024-06-14 20:24:29
塞尔维亚1-1英格兰,弗拉霍维奇建功,凯恩哑火,欧洲中国队丢人

塞尔维亚1-1英格兰,弗拉霍维奇建功,凯恩哑火,欧洲中国队丢人

邮轮摄影师阿嗵
2024-06-16 20:11:29
外媒:以色列面对真主党左右为难

外媒:以色列面对真主党左右为难

参考消息
2024-06-16 09:57:07
“这里不是中国!不会有人惯你们!”中国大妈已经沦落成世界公害

“这里不是中国!不会有人惯你们!”中国大妈已经沦落成世界公害

三月柳
2024-06-01 15:24:12
2024-06-17 01:48:49
moonfdd
moonfdd
福大大架构师每日一题
424文章数 7关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

南方医院回应教师因救人迟到:教学差错是最轻档处理

头条要闻

南方医院回应教师因救人迟到:教学差错是最轻档处理

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

房产
健康
数码
教育
旅游

房产要闻

万华对面!海口今年首宗超百亩宅地,重磅挂出!

晚餐不吃or吃七分饱,哪种更减肥?

数码要闻

PCIe 5.0 SSD终于要便宜了!群联E31T主控无缓存能跑12GB/s

教育要闻

大家都知道,这题目不会特别容易,看来还得是稳打稳的刷题才行啊

旅游要闻

@毕业生,江苏这些景区可享免票或优惠

无障碍浏览 进入关怀版