NTL密码算法开源库——模二整数

2021SC@SDUSC

NTL密码算法开源库——模二整数

综述

模2运算是一种二进制算法,不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。

模2运算

模2加法

两个序列模二相加,即两个序列中对应位相加,不进位,相同为0,不同为1。

1+1=0 0+0=0 1+0=1 0+1=1(相同即为0,否则为1)

模2减法

减法和加法一样,按加法规则运算。

0-0=0 1-1=0 0-1=1 1-0=1(相同即为0,否则为1)

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main()
{
    int k[100];//存放计算后的二进制数
    char s1[100],s2[100];//输入的两个二进制数
    int sum,sum1=0,sum2=0;
    int len1,len2;//两个字符数组的长度
    int i=0;
    gets(s1);
    gets(s2);
    len1 = strlen(s1);
    len2 = strlen(s2);
    while(s1[i]!='\0')//第一个二进制数转化为十进制数
    {
        sum1+= pow(2,len1-1)*(s1[i]-48);
        len1--;
        i++;
    }
    i=0;
    while(s2[i]!='\0')//第二个二进制数转化为十进制数
    {
        sum2+= pow(2,len2-1)*(s2[i]-48);
        len2--;
        i++;
    }
    i=0;
    sum = sum1+sum2;//两数和
    while(sum)//和转化为二进制
    {
        k[i] = sum%2;
        sum/=2;
        i++;
    }
    i=i-1;
    while(i>=0)//输出
    {
        printf("%d",k[i]);
        i--;
    }
    return 0;
}

模2乘法

多位二进制模2乘法类似于普通意义上的多位二进制乘法,或者是十进制乘法。不同之处在于后者累加中间结果(或称部分积)时采用带进位的加法,而模2乘法对中间结果的处理方式采用的是模2加法。

0×0=0 0×1=0 1×0=0 1×1=1(除11为1外,其余都为0)
代码实现

#include <stdio.h>
 #include <stdlib.h>
 #define LEN 64        //因子二进制位数的两倍,32位乘法结果不会超过64位
 
 int main()
 {
     unsigned int a = 0x13131313;
     unsigned int b = 0x23232323;
     unsigned int p = 0x00000001;
     unsigned int temp = 0;            
     unsigned int flags;                //用于判断做加法时是否溢出
     int i;
     int rlt[LEN] ={0};                //结果数组
     
     for(i=0; i<LEN; i++)                //主循环
     {
         flags = 0;
 
         if(b&p)                        //判断是否需要做加法
         {
             flags = temp;
             temp += a;
         }
 
         rlt[i] = (int) temp & 1;    //最低位丢弃,并保存至数组
         if(temp < flags)            //判断是否溢出
             temp += 0x80000000;
 
         temp >>= 1;                    //右移结果
        p <<= 1;
     }
 
    i = LEN-1;
     while(rlt[i] == 0) i--;            //丢弃结果前面的0
     for(; i>=0; i--)                //打印结果
         printf("%d", rlt[i]);
 
     printf("\n");
     
     return EXIT_SUCCESS;
 }

模2除法

多位二进制模2除法也类似于普通意义上的多位二进制除法,但是在如何确定商的问题上两者采用不同的规则。后者按带借位的二进制除法,根 据余数减除数够减与否确定商1还是商0,若够减则商1,否则商0。多位模2除法采用模2减法,不带借位的二进制减法,因此考虑余数够减除数与否是没有意义 的。实际上,在CRC运算中,总能保证除数的首位为1,则模2除法运算的商是由余数首位与除数首位的模2除法运算结果确定。因为除数首位总是1,按照模2 除法运算法则,那么余数首位是1就商1,是0就商0。

在下面的示例中,当余数位数与除数位数相同时,才进行异或运算,余数首位是1,商就是1,余数首位是0,商就是0。当已经除了几位后,余数位数小于除数,商0,余数往右补一位,位数仍比除数少,则继续商0,当余数位数和除数位数一样时,商1,进行异或运算,得新的余数,以此至被除数最后一位。

代码实现

int divide(int a, int b){
    if(!b)
        throw std::runtime_error("Divided can't be zero...");
    bool isNegative = false;
    bool isNegtive = false;
    if(getSign(a) ^ getSign(b))
        isNegtive = true;
    if(a < 0) a = add(~a,1);//求出a的绝对值
    if(b < 0) b = add(~b,1);//求出b的绝对值
    int res = 0;
    while(a >= b){
        res = add(res,1);
        a = subtraction(a,b);
    }
    if(isNegative)
        add(~res,1);
    return res;
}

具体运算实例见@回首~阑珊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元解~殇怀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值