NTL密码算法开源库-大整数ZZ类(一)
2021SC@SDUSC
NTL密码算法开源库-大整数ZZ类(一)
- 本章综述
- 代码分析
- 贝祖公式
本章综述
大整数ZZ类主要实现了任意长度大整数表示、最大公因数、Jacobi符号和素性检验。笔者将通过逐个分析ZZ.cpp源代码中函数的形式来一步步向读者展示NTL是如何实现上述功能的。
代码分析
(1)判断输入的I/O是否合法:
static NTL_CHEAP_THREAD_LOCAL long iodigits = 0;
static NTL_CHEAP_THREAD_LOCAL long ioradix = 0;static void InitZZIO()
{long x;x = (NTL_WSP_BOUND-1)/10; iodigits = 0;ioradix = 1;while (x) {x = x / 10;iodigits++;ioradix = ioradix * 10;}if (iodigits <= 0) TerminalError("problem with I/O");
}
注释:
这里的NTL_WSP_BOUND的值为(1L<<30)。因为长整型是一个有符号数,其二进制数的最高位是是符号位,所以一个长整型数最多表示范围是[-2147483647, 2147483647],所以最多有30位二进制数代表数字大小。1L代表1的数据类型是long类型的,也就是长整型。“<<30”代表将二进制的1左移30位。原来1在第一位,左移30位后,1在第31位。此时代表的数字是2147483648,超出了长整型表示范围,所以需要减一。此时代表的数字是2147483647,代表最大的长整型数的大小和位数。
Iodigits 变量记录最大长整型数的十进制位数(9位)
Ioradix 变量记录最大长整型数的十进制数+1(10位,1000000000)
Iodigits,Ioradix均为静态变量。
(2)接收大整数
istream& operator>>(istream& s, ZZ& x)
{long c; long cval; long sign; long ndigits; long acc;NTL_ZZRegister(a);if (!s) NTL_INPUT_ERROR(s, "bad ZZ input"); //若无输入,则直接报错if (!iodigits) InitZZIO(); //一个长整型最大接收的十进制位数是9位,该数据存在a = 0; // iodigits中。故先要将iodigits中数据进行初始化SkipWhiteSpace(s); //跳过输入时候有效数据前的空格c = s.peek(); //peek()探测指针,提前检测下一位,并不改变指针指向if (c == '-') {sign = -1;s.get();c = s.peek();}elsesign = 1; //确认该大整数的正负号cval = CharToIntVal(c); //接受大整数的时候只接受十进制,数字在0-9之间才合法if (cval < 0 || cval > 9) NTL_INPUT_ERROR(s, "bad ZZ input");ndigits = 0;acc = 0;while (cval >= 0 && cval <= 9) {acc = acc*10 + cval; ndigits++;if (ndigits == iodigits) { //用于九位九位的存储大整数,大整数超过九位会采用截断存储处理方法mul(a, a, ioradix);add(a, a, acc);ndigits = 0;acc = 0;}s.get(); //从输入流中提取已经存好的一位c = s.peek(); //探测下一位cval = CharToIntVal(c); //检测下一位输入是否合法}if (ndigits != 0) {long mpy = 1;while (ndigits > 0) {mpy = mpy * 10;ndigits--;}mul(a, a, mpy);add(a, a, acc);}if (sign == -1)negate(a, a);x = a;return s;
}
注释:
NTL_ZZRegister(a)这个函数相当于一种注册,生成了一个叫a的大整数类对象。和我们平时写的代码ZZ a;功能类似。
关于截断存储大整数的方法:NTL中定义了一个无符号长整型的数组(*cc),以十进制九位九位的将大整数进行拆分然后存入数组中。方便以后取用。
2.2.2输出大整数
(1)定义_ZZ_local_stack堆栈(采用结构体的方式定义)
struct _ZZ_local_stack {long top;Vec<long> data;_ZZ_local_stack() { top = -1; } //构造函数long pop() { return data[top--]; } //弹栈,出栈long empty() { return (top == -1); } //堆栈判空void push(long x); //压栈
};void _ZZ_local_stack::push(long x)
{if (top+1 >= data.length()) //判断堆栈的是否已满。若满,则扩容data.SetLength(max(32, long(1.414*data.length())));top++;data[top] = x;
}
注释:
堆栈的作用。因为大整数在运算的时候是从低位开始运算的,但是输出的时候是从高为开始逐渐输出的。所以低位做好运算之后适合进行压栈处理,不断地压栈,直到大整数运算结束再从堆栈中一一出栈,得到正确的输出结果。
(2)定义长整型输出函数
static
void PrintDigits(ostream& s, long d, long justify)
{NTL_TLS_LOCAL_INIT(Vec<char>, buf, (INIT_SIZE, iodigits)); //初始化数组buflong i = 0;while (d) {buf[i] = IntValToChar(d % 10); //将要输出的长整型数的每一位存到buf数组中d = d / 10;i++;}if (justify) {long j = iodigits - i;while (j > 0) {s << "0";j--;}}while (i > 0) {i--;s << buf[i]; //逐位输出长整型数据(只是*cc数组中的一个元素)}
}
(3)对于输出流运算符的重载
ostream& operator<<(ostream& s, const ZZ& a)
{ZZ b;_ZZ_local_stack S;long r;long k;if (!iodigits) InitZZIO();b = a;k = sign(b);if (k == 0) {s << "0"; //判断输出符号,若数值为零,则直接输出“0”return s;}if (k < 0) {s << "-"; //判断输出符号,若为负号,则先输出“-”negate(b, b);}do {r = DivRem(b, b, ioradix);S.push(r);} while (!IsZero(b));r = S.pop();PrintDigits(s, r, 0);while (!S.empty()) {r = S.pop();PrintDigits(s, r, 1);}return s;
}
贝祖公式
void XGCD(long& d, long& s, long& t, long a, long b)
{long u, v, u0, v0, u1, v1, u2, v2, q, r;long aneg = 0, bneg = 0;if (a < 0) {if (a < -NTL_MAX_LONG) ResourceError("XGCD: integer overflow");a = -a;aneg = 1;}if (b < 0) {if (b < -NTL_MAX_LONG) ResourceError("XGCD: integer overflow");b = -b;bneg = 1;}u1=1; v1=0;u2=0; v2=1;u = a; v = b;while (v != 0) {q = u / v;r = u % v;u = v;v = r; //到此为止是广义欧几里得算法u0 = u2; //从此开始是贝祖公式的求解v0 = v2;u2 = u1 - q*u2;v2 = v1- q*v2;u1 = u0;v1 = v0;}if (aneg)u1 = -u1;if (bneg)v1 = -v1;d = u;s = u1;t = v1; //最后返回u = sa+tb
}
贝祖公式的数学证明详见@回首,阑珊
NTL密码算法开源库-大整数ZZ类(一)相关推荐
- NTL密码算法开源库-大整数ZZ类(三)
2021SC@SDUSC NTL密码算法开源库-大整数ZZ类(三) 中国剩余定理 一次同余式 乘法逆元 简化剩余的等价描述 二次同余式 雅可比符号 中国剩余定理 //中国剩余定理模板代码 typede ...
- NTL密码算法开源库——大整数ZZ类(一)
2021SC@SDUSC 本章综述 大整数ZZ类主要实现了任意长度大整数表示.最大公因数.Jacobi符号和素性检验.笔者将通过逐个分析ZZ.cpp源代码中函数的形式来一步步向读者展示NTL是如何实现 ...
- NTL密码算法开源库——大整数ZZ类(四)
2021SC@SDUSC RSA算法原理 密钥生成的步骤 第一步,随机选择两个不相等的质数p和q. 爱丽丝选择了61和53.(实际应用中,这两个质数越大,就越难破解.) 第二步,计算p和q的乘积n. ...
- NTL密码算法开源库——大整数ZZ类(二)
2021SC@SDUSC 素数检测 (1)数学基础:费马小定理,二次探测定理,欧拉定理,Miller-Rabin素数测试,同余式, wilson定理,乘法逆元,简化剩余系 费马小定理:若存在整数 a ...
- NTL密码算法开源库——大整数上多项式(ZZX,GF2X)
2021SC@SDUSC 大整数上多项式(ZZX,GF2X) GF(2)域求两多项式的最大公因式 扩展欧几里得求两多项式最大公因式 GF(2)域求两多项式的最大公因式 //在GF(2)域中求两多项式的 ...
- NTL密码算法开源库--综述
2021SC@SDUSC NTL密码算法开源库--综述 项目综述 NTL算法库是开放源码的自由软件,具有专业处理任意精度大整数.实数的计算数论与计算代数的高性能可移植c++库,提供了任意大整数.任意精 ...
- NTL密码算法开源库(数论库)代码分析项目--综述
2021SC@SDUSC NTL密码算法开源库(数论库)代码分析项目--综述 项目综述 NTL开源代码库的安装和使用 NTL代码开源库主要解决的问题 项目分工以及核心代码的分配 项目综述 NTL算法库 ...
- 【NTL密码算法开源库-概述】
NTL库基本数据类型 ZZ: big integers(支持不等式运算) ZZ_p: big integers modulo p zz_p: integers mod "single pre ...
- NTL密码算法开源库——模二整数上的矩阵(mat_GF2)
2021SC@SDUSC 模二整数上的矩阵(mat_GF2) 矩阵运算 高斯消元 矩阵运算 具体代码 #include <NTL/matrix.h> #include <NTL/ve ...
最新文章
- MySQL优化篇:慢查询日志
- IOS开发笔记2-C语言基础复习
- CompletionService VS ExecutorService
- python爬取新闻存入数据库_python 爬取古诗文存入mysql数据库的方法
- 广州计算机应用能力考试,2017年广州职称计算机考试报名时间和科目
- linux 取出本机IP
- 利用curl去hack他人博客
- 转专业计算机的面试自我介绍,关于转专业面试自我介绍参考
- Delete出错分析总结(个人总结很到位) 0x0000007ff64426f87e(ucrtbased.dll)处(处于dataa.exe中)引发的异常:
- FineBI产品简介
- JavaWeb的学习(上)
- Android自定义View之滑杆内部带数字的SeekBar
- xp驱动和Win7驱动的区别
- 内嵌模式搭建Hive
- python读取Excel中关联表格的数据(只要是同Excel中
- 【小程序项目开发-- 京东商城】uni-app之商品列表页面 (下)
- 数梦工场7.5亿元都干点啥?
- 5G NR标准 第13章 重传协议
- 微位科技获首批区块链备案 中国电信积极布局
- WPS EXCEL中的VBA编程
热门文章
- Protobuf简单使用
- 秃鹫入门4,GDB调试与OpenCV图像库
- css实现箭头图标 伪类 图标
- 【C语言程序设计进阶-浙大翁恺】C语言笔记 文件
- 海康摄像头恢复出厂监控录像视频恢复
- 微信红包“昙花一现”?看传统企业中兴如何玩转“微信红包”
- 怎么把ppt文字大小设置一致_PPT滚动数字原来如此简单
- Java打印表格 Console/控制台
- 面试心得与总结---BAT、网易、蘑菇街等
- 如何看计算机cpu的好坏,cpu主要的性能参数有哪些、怎么看?教你几招轻松看懂CPU性能好坏...