8个回答

是否不存在 2022397710683865089 的倍数,在 256 进制下每一位都小于 26?

ZaolyloaZ
50个点赞 👍

根据生日悖论,在整体选项数目约为N的情况下,我们大概需要随机产生 \sqrt{N} 个随机样本,可以找到两个样本发生碰撞。而这里N=2022397710683865089, \sqrt{N} 略大于 10^9 ,这种规模在现在计算机算力下寻找碰撞还是可行的。

所以我们可以随机产生若干组 \sum{a_i 256^i} 数据,直到两组模2022397710683865089相等,那么它们的差就是2022397710683865089的倍数,唯一的问题是两者差可以产生某些系数是负数。

但是如果我们事先计算好 A=\sum{25*256^i} \pmod {2022397710683865089} , 然后随机产生若干组数据,直到两者之和关于2022397710683865089的余数为A,那么设两者分别为 \sum{a_i 256^i} ;\sum{b_i 256^i} ,其中 0\le a_i\le 12; 0\le b_i\le12 , 那么 \sum{(25-a_i-b_i)256^i} 就是2022397710683865089的倍数,可以符合条件。

所以现在的算法就可以是每次随机产生一组 \sum{a_i 256^i} ,其中 0\le a_i\le12 , 计算其模2022397710683865089的余数X,并且在一个map中匹配,如果遇到匹配的,那么已经找到结果;不然,将映射关系A-X => \sum{a_i 256^i} 加入map中。

这个算法唯一的问题是空间复杂度有些大,预期map最终规模到达数G项,比如这里 a_i 可以有16个,每个4比特,共64比特。每个关于2022397710683865089的余数也64比特。所以每项16字节,但是map本身数据结构占用空间会更大一些,所以最终将需要几百G内存空间(或者通过外存储)

用计算机搜索上面的数据竟然没有找到,然后改为21个,每个0~7 (3比特),找到了

16110906371565107114088456463416962548455164085513=2022397710683865089*7966240411791839601065921611017

对应256进制各位为

? v=[9,5,8,11,11,3,6,7,6,4,10,13,7,13,3,1,6,7,6,6,11]
%1 = [9, 5, 8, 11, 11, 3, 6, 7, 6, 4, 10, 13, 7, 13, 3, 1, 6, 7, 6, 6, 11]
? w=0;for(u=1,21,w+=v[u]*256^(u-1));w
%2 = 16110906371565107114088456463416962548455164085513
? %2 /2022397710683865089
%3 = 7966240411791839601065921611017

前面仅适用16个数没有找到结果,应该是数据没有随机产生而有一定规律的原因,改为随机数(rdrand)后,可以找到更小的结果了

? v=[22,12,14,15,3,17,13,21,13,12,14,4,12,11,4,16]
%5 = [22, 12, 14, 15, 3, 17, 13, 21, 13, 12, 14, 4, 12, 11, 4, 16]
? w=0;for(u=1,length(v),w+=v[u]*256^(u-1));w
%6 = 21288641178491305527004089323734567958
? w/M
%7 = 10526436549066624022
? v=[22,21,18,17,10,23,21,25,4,14,9,5,10,23,14,10]
%8 = [22, 21, 18, 17, 10, 23, 21, 25, 4, 14, 9, 5, 10, 23, 14, 10]
? w=0;for(u=1,length(v),w+=v[u]*256^(u-1));w
%9 = 13365439403129527017108993907161699606
? w/M
%10 = 6608709717442303254
? v=[25,9,5,5,21,10,20,25,13,18,4,13,5,12,4,18]
%11 = [25, 9, 5, 5, 21, 10, 20, 25, 13, 18, 4, 13, 5, 12, 4, 18]
? w=0;for(u=1,length(v),w+=v[u]*256^(u-1));w
%12 = 23947116900646907489316813862934481177
? w/M
%13 = 11840953326904871193
? v=[7,14,17,3,13,9,18,20,7,21,14,18,14,15]
%14 = [7, 14, 17, 3, 13, 9, 18, 20, 7, 21, 14, 18, 14, 15]
? w=0;for(u=1,length(v),w+=v[u]*256^(u-1));w
%15 = 305350926084413285478724222914055
? w/M
%16 = 150984608255495
? v=[16,19,17,25,17,4,17,4,11,17,6,8,13,11]
%18 = [16, 19, 17, 25, 17, 4, 17, 4, 11, 17, 6, 8, 13, 11]
? w=0;for(u=1,length(v),w+=v[u]*256^(u-1));w
%19 = 224138954966970736913977692984080
? w/M
%20 = 110828327080720

==================

由于发现上面随机搜素得到结果仅M=2022397710683865089的 10^{14} 倍左右,考虑到实际上最小值可能会更小,于是试着写了一个从小到达穷举M的所有倍数的程序,结果发现可行,比如符合条件的最小的两个M的倍数为

399570568233696659924615960586
482826933321103562173598208264

? 399570568233696659924615960586/2022397710683865089
%1 = 197572696074
? dec256(x)={local(v,r);v=[];while(x>0, r=x%256;v=concat(v,r);x=(x-r)/256);v}
%2 = (x)->local(v,r);v=[];while(x>0,r=x%256;v=concat(v,r);x=(x-r)/256);v
? dec256(399570568233696659924615960586)
%3 = [10, 24, 0, 7, 18, 9, 23, 3, 3, 7, 21, 11, 5]
? 482826933321103562173598208264/2022397710683865089
%4 = 238739853576
? dec256(482826933321103562173598208264)
%5 = [8, 17, 1, 21, 15, 0, 14, 16, 22, 20, 25, 24, 6]

继续搜索还有更多解

21159812990124519421490800036869
40569463943266575422535274335000
41998066124008896033080034528009
82241326808125838922727812105746
102290065467826344940701685910016
123603694930202511916441141315584
164082791611487977850921645053966
202907044144335292983773881635340
202989060075659743553330127378453
224138954966970736913977692984080
224216344324832963943073229312007
244186462983276954486239894045204
265495763163774625445539241721871
285304333116577247064887252226579
305350926084413285478724222914055
326347004503472631285123133150983
326500820975724278839371788519682
346310970923737134025665724482314
365724021399894405172778907537927
405727739481875214460523584749833
427597196706723621510210402847253
427833029110299719634015303959065
447246079586456990781128487014678
466499782688679145355133151810576
487332745619991778084782080722445
508090831233217456451293018132996

上面列表包含了所有256进制下长度不超过14的解,比如最后一个

? dec256(508090831233217456451293018132996)
%2 = [4, 18, 1, 12, 7, 21, 0, 2, 23, 3, 5, 2, 13, 25]

对应C++搜索代码在

github.com/emathgroup/s

需要使用gmp和openmp,编译选项

g++ -O3 gmpsrch.cpp -ogmpsrch -fopenmp -lgmpxx -lgmp

编辑于 2024-05-05 09:37・IP 属地上海
mathe
自由评论 (0)
分享
Copyright © 2022 GreatFire.org