纯lsp实现lsp的超大整数四则运算
本帖最后由 tryhi 于 2021-8-15 22:06 编辑没想到上一贴那么快被人破解,纯lsp实现RAS非对称加密,其实我自己试了一下,32位确实太弱了,可以被秒破,那么高位数的运算势必要突破lsp的计算限制,本以为超大数运算以为很简单,结果发现想要速度快是真的难,搞了一整晚400行代码构造了13个函数才完成了基础的运算功能。
欢迎找BUG,找到加币。
先来个小实验,(* 2 2000000000),一句2乘以20亿的代码,正常来说应该得到40亿,但是CAD却返回了-294967296的结果,意味着整数计算超限了,不过还好可以使用浮点数来计算,但是浮点数也是有限制的,到了17位数之后,计算结果已经不可靠了,误差非常大了,如果要做1024的RAS加密,至少需要计算到309位的整数,显然不太可能,所以尝试了一下突破极限。
那么需要重新定义什么超大整数,结构是怎样的,我定义了一组无限长度的列表,用10000进制,比如(1234 5678 7890)就代表整数的123456787890,比如(1 2 3 4)就代表整数的1000200030004,负数则第一个值为负,第一个不允许为0,除非本身就是0,用(0)表示。
该系列函数可以计算任意大小的整数,比如两个100位长的数相乘,理论上无上限。
超大整数数据类型,类型为10000进制的表,前面为高位,后面为低位。
最高位不允许为0(除非本身为0)。
第一位如果为负数,则代表这是一个超大负数。
之所以选用10000是因为10000的平方还在lsp的整数范围内,而十万的平方超出lsp的整数范围。
try-bignum* 超大整数相乘
try-bignum-isfu 判断一个超大整数是否为负数(0定义为正数)
try-bignum*-1 求一个超大整数的相反数
try-bignum- 超大整数相减
try-bignum+ 超大整数相加
try-bignum> 超大整数a是否大于btry-bignum< 超大整数a是否小于b
try-bignum/ 超大整数相除
try-bignum% 超大整数求模(余数)
try-bignum/_sy 超大整数相除(返回商跟余数)
try-fix->bignum 将一个普通整数(实数)转换为超大整数
try-bignum->fix 将一个超大整数转换为普通整数(超限则转为实数)
try-bignum->str 将一个超大整数转换为字符串
try-str->bignum 将用数字表示的字符串转换为一个超大整数
下面例子展示的是两个50位数的整数相乘
(setq num1(try-str->bignum "12345678901234567890123456789012345678901234567890")
x*(try-bignum* num1 num1)
)
(try-bignum->str x*)
续:---------------2021-6-28 13:05----------------
自己发现了加法函数有问题,没有成功进位,已更新附件
repeat (length a);循环相减
(setq i(1+ i))
(setq xa(nth i a)
xb(nth i b))
(if (not xb)(setq xb 0))
(setq
cha(+ xa xb qian)
)
(if (> cha 9999);溢出进位
(setq qian 1 cha(- cha 10000))
(setq qian 0)
)
(setq ret(cons cha ret))
)
""????????????????????????????""
(while (= (car ret)0);循环删除头部的0
(setq ret(cdr ret))
) (defun try-fix->bignum (n / fushu m x)
(if (< n 0)
(setq fushu t
n (- n)
)
)
(while (/= 0 n)
(setq m (fix (rem n 10000))
n (fix (/ n 10000))
x (cons m x)
)
)
(if (not x)
(setq x '(0))
)
(if fushu
(cons (- (car x)) (cdr x))
x
)
) 本帖最后由 baitang36 于 2021-6-28 08:08 编辑
(setq num2(try-str->bignum "2"))
(setq num1(try-str->bignum "-2")
x*(try-bignum* num1 num2)
)
(try-bignum->str x*)
结果正确。
(setq num1(try-str->bignum "-2")
x*(try-bignum* num1 num1)
)
是求平方
请继续你的表演 本帖最后由 流氓兔 于 2021-6-28 14:10 编辑
(setq num2(try-str->bignum "12345678901234567890123456789012345678901234567890"))
(setq num1(try-str->bignum "-12345678901234567890123456789012345678901234567890")
x*(try-bignum* num1 num2)
)
(try-bignum->str x*)
已改 问题解决!牛! 流氓兔 发表于 2021-6-28 07:59
(setq num2(try-str->bignum "12345678901234567890123456789012345678901234567890"))
(setq num1(try-st ...
最重要的代码成功了,离ras 公钥 解密,近在咫尺了,等您1024 2048 lsp
请继续你的表演 太厉害了,请继续。 楼主威武,学习了 感谢大神的奉献!
页:
[1]
2