python 有限域函数库_有限域(4)——程序实现有限域的运算
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址
http://www.cnblogs.com/Colin-Cai/p/9652019.html
作者:窗户
QQ/微信:6679072
E-mail:6679072@qq.com
前一章,我们知道了使用素域的多项式环的商环构造任意的有限域的方法。这一章里,我们就用程序实现任意有限域里的运算。
我在这里还是同第一章一样,选择用Scheme来描述。
数据表示
首先,我们需要的一个参数就是域的特征,记为 p
根据上章分析,我们还需要一个不可分多项式,称为生成多项式,记为 poly
上一章还有一个重要结论是,如果poly的次数是n, 那么所有的次数小于n的多项式共计pn个,分别属于不同的商集,除此之外并无其他商集,那么也就对应着最后的域的元。
所以,我们这里就以这pn个小于n次的多项式来代表该域的所有元,这种表示是合理的。
现在,我们来考虑不可分多项式以及域里每个元的计法:
我们用一个长度为n+1的list来记录生成多项式poly就可以了(n次多项式一共n+1个系数),这个list的第0项、第1项、...第n-1项、第n项分别对应着poly的n次系数、n-1次系数、...1次系数、0次系数(常数项)。比如,特征2素域下的3次不可分多项式 x3+x+1,记作(1 0 1 1)。
而对于每个域里的元,我们也用上述的写法来记,只是,我们把这个多项式补齐成n-1次,没有的项系数都为0,比如在2特征、生成多项式x3+x+1的域下,元[x+1]记为(0 1 1),也就是一个域下所有的元,记录成list都是生成多项式的次数这么长。
函数定义
我们再来定义函数接口,我们就这样去表示有限域里的加减乘除:
(add poly p a b) 代表p特征、生成多项式为poly时,a+b
(sub poly p a b) 代表p特征、生成多项式为poly时,a-b
(mul poly p a b) 代表p特征、生成多项式为poly时,a*b
(div poly p a b) 代表p特征、生成多项式为poly时,a/b
当然,除法涉及到求逆,
(inv poly p a) 代表p特征、生成多项式为poly时,a的逆
程序设计
有了上述准备,再来看第一章的素域里的加减乘除:
;加法
(define (addp p a b)
(if (>= (+ a b) p) (- (+a b) p)
(+a b)
)
)
;减法
(define (subp p a b)
(addp p a (if (zero? b) 0 (-p b)))
)
;乘法
(define (mulp p a b)
(remainder (*a b) p)
)
;求逆
(define (invp p a)
(define (pow n a b)
(cond
((zero?n) a)
((zero? (remainder n 2)) (pow (quotient n 2) a (mulp p b b)))
(else (pow (quotient n 2) (mulp p a b) (mulp p b b)))
)
)
(pow (- p 2) 1a)
)
;除法
(define (divp p a b)
(mulp p a (invp p b))
)
加法和减法很容易做,一个map,对应的都是相同次数的项的系数,然后做合并同类项即可。
(define (addp p a b)
(if (>= (+ a b) p) (- (+a b) p)
(+a b)
)
)
(define (subp p a b)
(addp p a (if (zero? b) 0 (-p b)))
)
而对于inv求逆来说,因为pn阶域里,除0之外的所有的元乘法构成一个群,所以任何一个元的pn-1 次幂就是自己的逆元。
(define (inv poly p a)
(define (pow poly p a n)
(if (zero?n)
(append (make-list (- (length a) 1) 0) '(1)) ;指数为0的时候就是1元
(mul poly p a (pow poly p a (- n 1))) ;否则就是a和a的n-1次幂的乘积
)
)
(define (pow-n p n)
(if (zero? n) 1 ;指数为0的时候就是1(* p (pow-n p (- n 1))) ;否则就是p和p的n-1次幂的乘积
)
)
(pow poly p a (- (pow-n p (length a)) 2))
)
于是,除法也就顺理成章:
(define (div poly p a b)
(mul poly p a (inv poly p b))
)
当然,上面的求幂算法是个效率很差的算法。我们可以改个对数级的算法,此处不多解释。理论依据我之前的文章《RSA简介(二)——模幂算法》
于是我们效率高的求逆如下:
(define (inv poly p a)
(define (pow poly p a n)
(define (pow2 n r x)
(cond
((zero?n) r)
((zero? (remainder n 2)) (pow2 (quotient n 2) r (mul poly p x x)))
(else (pow2 (quotient n 2) (mul poly p r x) (mul poly p x x)))
)
)(pow2 n (append (make-list(- (length a) 1) 0) '(1)) a)
)
(define (pow-n p n)
(define (pow2 n r x)
(cond
((zero?n) r)
((zero? (remainder n 2)) (pow2 (quotient n 2) r (*x x)))
(else (pow2 (quotient n 2) (* r x) (*x x)))
)
)
(pow2 n1p)
)
(pow poly p a (- (pow-n p (length a)) 2))
)
关键是乘法,做起来有些难,对lisp没有太多基础且不习惯函数式编程的人可能很难写出来。
两个元的乘法结果应该是其多项式乘法然后对生成多项式做带余除法得到的余数。
从而,可以先构造两个函数,一个函数是多项式乘法:
(define (poly-mul p a b)
(map (lambda (x) (remainder x p))
(cdr
(foldr
(lambda (x y)
(cons
(+ 1(car y))
(map+(append (make-list (- (length b) (car y) 1) 0) (map (lambda (c) (* c x)) a) (make-list (car y) 0))
(cdr y)
)
)
)
(make-list (+ (length a) (length b)) 0)
b
)
)
)
)
一个用迭代实现的带余除法,如下
(define (division a b)
(define (division-iter a b b_len times)
(cond
((zero? times) a)
(else
(division-iter
(append
(map
(lambda (x y) (modulo (- x (* y (divp p (car a) (car b)))) p))
(cdr (take a b_len))
(cdr b)
)
(drop a b_len)
)
b
b_len
(- times 1)
)
)
)
)
(division-iter a b (length b) (- (length a) (length b) -1))
)
有了上述基础,就可以构造乘法,乘法就是
(define (mul poly p a b)
(division
(poly-mul p a b)
poly
)
)
多项式乘法poly-mul的实现中用到了foldr算子,这个算子并不是定义在Scheme任何标准中的,独属于racket。不过这个算子实际上就是著名的SICP里的accumulate算子,我也一直很奇怪如此重要的算子为什么不在标准中体现。以下是这个算子的定义。
(define (foldr op init lst)
(if (null?lst) init
(op (car lst) (foldr op init (cdr lst)))
)
)
测试
以上,域的加减乘除都有了。
我们可以测试一下,阶最小的不是素域的有限域是4阶,特征为2。
特征2素域下的不可分2次多项式只有一个,x2+x+1
(define poly '(1 1 1)) ;生成多项式
(define p 2) ;特征
(define (list-all)
(define (sub1 x)
(foldr (lambda (m n) (if (zero? (apply * n)) (cons m n) (cons (- 1 m) n))) '() x)
)
(define (func2 x y)
(let*((a (car x))
(b (cdr x))
(asum (apply+a))
(bsum (apply+b))
)
(cond
((zero? (+asum bsum)) (cons x y))
((zero?bsum) (func2 (cons (sub1 a) (sub1 b)) (cons x y)))
(else(func2 (cons a (sub1 b)) (cons x y)))
)
)
)
(let ((m (make-list (- (length poly) 1) (- p 1))))
(func2 (cons m m)'())
)
)
(for-each
(lambda (x) (display (string-append
(format"~a+~a=~a ~a-~a=~a ~a*~a=~a"(car x)
(cdr x)
(add p (car x) (cdr x))
(car x)
(cdr x)
(sub p (car x) (cdr x))
(car x)
(cdr x)
(mul poly p (car x) (cdr x))
)
(if (zero? ( foldr + 0(cdr x)))"\n"(format"~a/~a=~a\n"(car x)
(cdr x)
(div poly p (car x) (cdr x))
)
)
)
)
)
(list-all)
)
上面测试代码中poly和p可以任意改,这里只以4阶域为测试对象。
以上运行结果如下:
(0 0)+(0 0)=(0 0) (0 0)-(0 0)=(0 0) (0 0)*(0 0)=(0 0)
(0 0)+(0 1)=(0 1) (0 0)-(0 1)=(0 1) (0 0)*(0 1)=(0 0) (0 0)/(0 1)=(0 0)
(0 0)+(1 0)=(1 0) (0 0)-(1 0)=(1 0) (0 0)*(1 0)=(0 0) (0 0)/(1 0)=(0 0)
(0 0)+(1 1)=(1 1) (0 0)-(1 1)=(1 1) (0 0)*(1 1)=(0 0) (0 0)/(1 1)=(0 0)
(0 1)+(0 0)=(0 1) (0 1)-(0 0)=(0 1) (0 1)*(0 0)=(0 0)
(0 1)+(0 1)=(0 0) (0 1)-(0 1)=(0 0) (0 1)*(0 1)=(0 1) (0 1)/(0 1)=(0 1)
(0 1)+(1 0)=(1 1) (0 1)-(1 0)=(1 1) (0 1)*(1 0)=(1 0) (0 1)/(1 0)=(1 1)
(0 1)+(1 1)=(1 0) (0 1)-(1 1)=(1 0) (0 1)*(1 1)=(1 1) (0 1)/(1 1)=(1 0)
(1 0)+(0 0)=(1 0) (1 0)-(0 0)=(1 0) (1 0)*(0 0)=(0 0)
(1 0)+(0 1)=(1 1) (1 0)-(0 1)=(1 1) (1 0)*(0 1)=(1 0) (1 0)/(0 1)=(1 0)
(1 0)+(1 0)=(0 0) (1 0)-(1 0)=(0 0) (1 0)*(1 0)=(1 1) (1 0)/(1 0)=(0 1)
(1 0)+(1 1)=(0 1) (1 0)-(1 1)=(0 1) (1 0)*(1 1)=(0 1) (1 0)/(1 1)=(1 1)
(1 1)+(0 0)=(1 1) (1 1)-(0 0)=(1 1) (1 1)*(0 0)=(0 0)
(1 1)+(0 1)=(1 0) (1 1)-(0 1)=(1 0) (1 1)*(0 1)=(1 1) (1 1)/(0 1)=(1 1)
(1 1)+(1 0)=(0 1) (1 1)-(1 0)=(0 1) (1 1)*(1 0)=(0 1) (1 1)/(1 0)=(1 0)
(1 1)+(1 1)=(0 0) (1 1)-(1 1)=(0 0) (1 1)*(1 1)=(1 0) (1 1)/(1 1)=(0 1)
python 有限域函数库_有限域(4)——程序实现有限域的运算相关推荐
- python 有限域函数库_深入比特币之有限域运算
这是深入比特币系列文章,主要是面向想深入理解比特币原理的开发者. 椭圆曲线加密(elliptic curve cryptography)是比特币交易工作的核心.比特币交易的签名验证离不开椭圆曲线加密. ...
- c int转字符串_【C++实现python字符串函数库】字符串匹配函数startswith与endswith
[C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...
- 基于TIA博途SCL语言的设备累计运行时间FB函数库_具体方法及程序示例
基于TIA博途SCL语言的设备累计运行时间FB函数库_具体方法及程序示例 如下图所示,打开博途,新建一个项目,添加一个CPU,在该CPU中,添加一个FB,命名为:设备累计运行时间, 双击打开该FB,在 ...
- python rstrip函数_【C++实现python字符串函数库】strip、lstrip、rstrip方法
[C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...
- python语言函数库_Python 的标准库,从0到1学Python
1.1. 介绍软件测试业务流程的梳理技巧 - 乐搏软件教育 - 软件测试 - Powered By EduSoho17lebo.com Python 的标准库包括了很多的模块, 从 Python 语 ...
- python人脸识别库_基于Python的face_recognition库实现人脸识别
Python Python开发 Python语言 基于Python的face_recognition库实现人脸识别 一.face_recognition库简介 face_recognition是Pyt ...
- python 宏处理库_常用的Python库,给大家分享一下!
Tkinter---- Python默认的图形界面接口. Tkinter是一个和Tk接口的Python模块,Tkinter库提供了对Tk API的接口,它属于Tcl/Tk的GUI工具组.Tcl/Tk是 ...
- python 函数式编程 库_使用Python的toolz库开始函数式编程的方法
在这个由两部分组成的系列文章的第二部分中,我们将继续探索如何将函数式编程方法中的好想法引入到 Python中,以实现两全其美. 在上一篇文章中,我们介绍了不可变数据结构 . 这些数据结构使得我们可以编 ...
- python split函数 空格_最易懂的Python新手教程:从基础语法到代码详解
导读:本文立足基础,讲解Python和PyCharm的安装,及Python最简单的语法基础和爬虫技术中所需的Python语法. 作者:罗攀 蒋仟 如需转载请联系华章科技 本文涉及的主要知识点如下: P ...
- python程序设计试题库_最新《Python程序设计》试题库资料
精品文档 精品文档 < Python 程序设计>题库 一.填空题 第一章 基础知识 1 . Python 安装扩展库常用的是 _______ 工具.( pip ) 2 . Python 标 ...
最新文章
- android 4.4从图库选择图片,安卓6.0,从系统图库选择照片,裁剪,并显示的问题。...
- LNMP部署(分享十七)
- 4位无符号比较器设计
- 损失函数_SRGAN损失函数(目标函数)详解
- 【会议】2008-10-27
- OpenCV辅助对象(help objects)(2)_Range
- gp3688写频线制作_摩托罗拉GP3688写频软件
- HDU-1045 Fire NetFire Net 最大团
- input 输入时间html,HTML “input time小时分钟”输入控件简介说明
- android获取浏览器cookie,获取浏览器cookie
- 解析力 (2)空间采样 和 奈奎斯特
- 苹果6解锁ID锁支持ios13以下所有系统
- 严格约束选股条件 能否找到跑赢市场的好公司?
- php path_info orig_path_info
- 2022N1叉车司机题库及在线模拟考试
- 通过wifi共享使Linux设备连接网络
- EtherCAT从站协议栈代码笔记之ecat_def.h
- 淘宝抢购Python脚本
- 一次哔哩哔哩面试经历
- Java 之 覆写, 重载, 隐藏, 遮蔽, 遮掩