/* program: Large integer operations
 * Made by:  Daiyyr
 * date:  2013/07/09

* This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 */

//开源代码,引用请务必遵守GNU规则

//未完待续,尚缺 乘方、除法、取模运算

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

//#define DEBUG

#ifdef DEBUG
    #define LOG(format, args...)   do { printf(format, ## args); \
                                   printf("\n");}\
                                   while(0)
                                   
    #define DBG() printk("[%s]:%d => \n",__FUNCTION__,__LINE__)
#else
    #define LOG(format, args...);
    #define DBG()
#endif

#define LOGE(format, args...)   do { printf(format, ## args); \
                                 printf("\n");}\
                                 while(0)

#define LENGTH 1000   //max digit of this long number

struct charnumber{
    char sign;          //0 for positive, 1 for negative
    int length;
    unsigned char* array;//low index of this array is for high digit of the number
    unsigned char* pointerforfree;
};

int char2interger(unsigned char onebyte){
    if (onebyte < 10)
        return onebyte;
    else
        return ((onebyte>>4)*10)+(onebyte&15);
}

struct charnumber* interger2charnumber(signed long int number){
    unsigned char charnumber[LENGTH/2];
    int i=0;
    struct charnumber *target;
    LOG("num: %ld", number);
    target = malloc(sizeof(struct charnumber));
    if (number<0){
        target->sign=1;
        number = -number;
        LOG("num:%ld", number);
    }
    else{
        target->sign=0;
    }
    while(number!=0){
        charnumber[i]=number%10;
        LOG("i:%d, num:%ld, char:%d", i, number, charnumber[i]);
        number/=10;
        charnumber[i]|=number%10<<4;
        LOG("i:%d, num:%ld, char:%d", i, number, charnumber[i]);
        number/=10;
        i++;
    }
    target->length=i;
    target->array = malloc(target->length);
    target->pointerforfree = target->array;
    for(i--;i>(target->length-1)/2;i--){   //Reverse
        LOG("length=%d, i=%d, left=%d, right=%d", target->length, i, charnumber[target->length-i-1], charnumber[i]);
        charnumber[i] = charnumber[i] + charnumber[target->length-i-1];
        charnumber[target->length-i-1] = charnumber[i] - charnumber[target->length-i-1];
        charnumber[i] = charnumber[i] - charnumber[target->length-i-1];
    }
    memcpy(target->array, charnumber, target->length);    
    for(i=0;i<target->length;i++)
        LOG("i:%d:%d", i, char2interger(target->array[i]));    
    LOG("~~length:%d", target->length, target->length);
    return target;
}
 
char* charnumber2string(struct charnumber* charnumber){
    int length = 2*charnumber->length+1;
    char* showchar = malloc(length);
    int i;

LOG("string signed:%d", charnumber->sign);
    if(charnumber->sign!=0)
        showchar[0]='-';
    else
        showchar[0]='+';
    for(i=0; i<charnumber->length; i++){
        showchar[2*i+1]='0'+(charnumber->array[i]>>4);
        showchar[2*i+2]='0'+(charnumber->array[i]&15);
        LOG("%d:  %x, %c%c",i, charnumber->array[i], showchar[2*i+1],showchar[2*i+2]);
    }
    showchar[length]='\0';
    if (!strcmp(showchar, "+"))
        strcpy(showchar, "+0");
    else if(showchar[1]=='0')
        showchar++, showchar[0]=charnumber->sign ? '-' : '+';
    return showchar;
}

struct charnumber* string2charnumber(char* string){
    if(!(string[0]=='-' || string[0]=='+' || (string[0]>='0' && string[0]<='9'))){
        printf("error: in string2charnumber, invalid input number!\n");
        return NULL;
    }
    struct charnumber *number;
    char* temp = malloc(strlen(string));
    int i, odd;

strcpy(temp, string);
    number = malloc(sizeof(struct charnumber));
    if(temp[0]=='-'){
        number->sign = 1;
        temp++;        
    }
    else{
        number->sign = 0;
    }
    odd = strlen(temp)%2;
    LOG("strlen(temp): %d, odd=%d\n", strlen(temp), odd);
    number->length = strlen(temp)/2 + odd;
    number->array = malloc(number->length);
    number->pointerforfree = number->array;
    for(i=number->length-1; i>=0; i--){
        if(i){
            if(temp[i*2+1-odd] > '9' || temp[i*2+1-odd] < '0' || temp[i*2-odd] > '9' || temp[i*2-odd] < '0'){
                printf("error! in string2charnumber, invalid input number!\n");
                LOG("temp[%d]=%x, temp[%d]=%x",i*2+1-odd, temp[i*2+1-odd], i*2-odd,  temp[i*2-odd]);
                return NULL;
            }
            number->array[i]=(temp[i*2+1-odd] - '0') + ((temp[i*2-odd] - '0') << 4);
            LOG("number->array[%d]=%x", i, number->array[i]);
        }
        else{
            number->array[0]=odd ? temp[0] - '0'   :  (temp[1] - '0') + ((temp[0] - '0') << 4);
            LOG("temp[1]:%d, temp[0]:%d,  '0':%d,  number->array[%d]=%x",temp[1],temp[0],  '0', i, number->array[i]);
        }
    }
    return number;
}

struct charnumber* minusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2);

struct charnumber* plusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){
    struct charnumber *temp1, *temp2, *sum;

if(!!charnumber1->sign != !!charnumber2->sign){
        temp1 = malloc(sizeof(struct charnumber));
        temp2 = malloc(sizeof(struct charnumber));
        memcpy(temp1, charnumber1, sizeof(struct charnumber));
        memcpy(temp2, charnumber2, sizeof(struct charnumber));
        temp2->sign = !temp2->sign;
        sum = minusCharNumber(temp1, temp2);
        free(temp1->pointerforfree), free(temp2->pointerforfree), free(temp1), free(temp2);
        return sum;
    }
    int i, carry = 0;

if(charnumber1->length >= charnumber2->length){
        temp1 = charnumber1;
        temp2 = charnumber2;
    }
    else{
        temp1 = charnumber2;
        temp2 = charnumber1;
    }
    sum = malloc(sizeof(struct charnumber));
    sum->sign = temp1->sign;
    LOG("signed:%d", sum->sign);
    sum->array = malloc(temp1->length+1);
    sum->pointerforfree = sum->array;
    for(i=temp1->length; i>temp1->length-temp2->length; i--){       //遍历较小数的位数
        sum->array[i]=(carry + temp1->array[i-1]&15) + (temp2->array[i-(temp1->length+1-temp2->length)]&15);
        carry = 0;
        if(sum->array[i]>9){
            sum->array[i] = 6 + sum->array[i];
        }
        sum->array[i]=sum->array[i] + (temp1->array[i-1]>>4<<4) + (temp2->array[i-(temp1->length+1-temp2->length)]>>4<<4);
        if(sum->array[i]>159)
            sum->array[i] -= 160, carry = 1;
        LOG("i: %d, 0x%x, 1:0x%x, 2:0x%x", i, sum->array[i], temp1->array[i-1], temp2->array[i-(temp1->length+1-temp2->length)]);
    }
    while(carry && i>=1){   //在遍历完较小数的位数后,处理可能的进位
        sum->array[i] = temp1->array[i-1] + 1;
        if((sum->array[i]&15) == 10){
            LOG("carry1.0, %x", sum->array[i]);
            sum->array[i]=(sum->array[i]&240) + 16;
            LOG("carry1.1, %x", sum->array[i]);
            if(sum->array[i] == 160){
                sum->array[i]=0;
                carry=1;
                LOG("carry2");
            }
            else
                carry=0;
        }
        else
            carry=0;
        i--;
    }
    if(carry){
        sum->array[0]=1;
        sum->length = temp1->length+1;
    }
    else{
        sum->array++;
        memcpy(sum->array, temp1->array, i);
        sum->length = temp1->length;
    }
    return sum;
}

struct charnumber* multiplyCharNumberAndInt(struct charnumber* charnumber, int n){
    long i;
    struct charnumber *result, *temp;
    result = interger2charnumber(0);
    for(i=0; i<n; i++){
        temp = result;
        result = plusCharNumber(result, charnumber);
        free(temp->pointerforfree);
        free(temp);
    }
    
    if(charnumber->sign ^ (n<0) )
        result->sign = 1;
    else
        result->sign = 0;
    
    return result;
}

int mypow(int x, int y){
    int i, sum=1;
    for(i=0; i<y; i++){
        sum=sum*x;
    }
    return sum;
}

struct charnumber* multiplyCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){
    int i, orisign1, orisign2;
    struct charnumber* result, *temp1, *temp2, *tempforfree1, *tempforfree2, *tempforfree3;
    
    orisign1 = charnumber1->sign;
    orisign2 = charnumber2->sign;
    charnumber1->sign = 0;
    charnumber2->sign = 0;
    
    if(charnumber1->length >= charnumber2->length){
        temp1 = charnumber1;
        temp2 = charnumber2;
    }
    else{
        temp1 = charnumber2;
        temp2 = charnumber1;
    }
    result = interger2charnumber(0);
    LOG("t1length:%d, t2length:%d", temp1->length, temp2->length);
    for(i=0; i<temp2->length; i++){
        tempforfree1 = multiplyCharNumberAndInt(temp1, temp2->array[i]&15);
        tempforfree2 = multiplyCharNumberAndInt(tempforfree1, mypow(10, (temp2->length-i)*2-2));
        tempforfree3 = result;
        result = plusCharNumber(tempforfree3, tempforfree2);
        free(tempforfree1->pointerforfree), free(tempforfree2->pointerforfree), free(tempforfree3->pointerforfree), free(tempforfree1), free(tempforfree2), free(tempforfree3);
        LOG("multip1 i=%d, t1=0x%x, t2=0x%x, t3=0x%x, res=0x%x", i, tempforfree1->array[i], tempforfree2->array[i], tempforfree3->array[i], result->array[i]);
        tempforfree1 = multiplyCharNumberAndInt(temp1, temp2->array[i]>>4);
        tempforfree2 = multiplyCharNumberAndInt(tempforfree1, mypow(10, (temp2->length-i)*2-1));
        LOG("tempforfree1:%s, tempforfree2:%s",charnumber2string(tempforfree1), charnumber2string(tempforfree2));
        tempforfree3 = result;
        result = plusCharNumber(tempforfree3, tempforfree2);
        free(tempforfree1->pointerforfree), free(tempforfree2->pointerforfree), free(tempforfree3->pointerforfree), free(tempforfree1), free(tempforfree2), free(tempforfree3);
    }
    charnumber1->sign = orisign1;
    charnumber2->sign = orisign2;
    
    if(charnumber1->sign ^ charnumber2->sign ){
        result->sign = 1;
    }
    else
        result->sign = 0;
    return result;
}

struct charnumber* minusCharNumber(struct charnumber* charnumber1, struct charnumber* charnumber2){    
    struct charnumber *temp1, *temp2, *difference;
    
    if(!!charnumber1->sign != !!charnumber2->sign){
        temp1 = malloc(sizeof(struct charnumber));
        temp2 = malloc(sizeof(struct charnumber));
        memcpy(temp1, charnumber1, sizeof(struct charnumber));
        memcpy(temp2, charnumber2, sizeof(struct charnumber));
        temp2->sign = !temp2->sign;
        difference = plusCharNumber(temp1, temp2);
        free(temp1->pointerforfree), free(temp2->pointerforfree), free(temp1), free(temp2);
        return difference;
    }

int i, borrow = 0;
    difference = malloc(sizeof(struct charnumber));
    if(charnumber1->length > charnumber2->length){
        temp1 = charnumber1;
        temp2 = charnumber2;
        difference->sign = temp1->sign;
    }
    else if(charnumber1->length < charnumber2->length){
        temp1 = charnumber2;
        temp2 = charnumber1;
        difference->sign = -temp1->sign;
    }
    else{
        for(i=0; i<charnumber1->length; i++){
            if(charnumber1->array[i] > charnumber2->array[i]){
                temp1 = charnumber1;
                temp2 = charnumber2;
                difference->sign = temp1->sign;
                break;
            }
            else if(charnumber1->array[i] < charnumber2->array[i]){
                temp1 = charnumber2;
                temp2 = charnumber1;
                difference->sign = -temp1->sign;
                break;
            }
        }
        if(i == charnumber1->length)
            return interger2charnumber(0);
    }
    difference->array = malloc(temp1->length);
    difference->pointerforfree = difference->array;
    for(i=temp1->length-1; i>=temp1->length-temp2->length; i--){       //遍历较小数的位数
        difference->array[i]=(borrow + temp1->array[i]&15) - (temp2->array[i-(temp1->length-temp2->length)]&15);
        if(difference->array[i]>10){
            difference->array[i] = difference->array[i]-6;
        }
        LOG("minus:i: %d, 0x%x, 1:0x%x, 2:0x%x", i, difference->array[i], temp1->array[i], temp2->array[i-(temp1->length-temp2->length)]);
        borrow = 0;

difference->array[i]=difference->array[i] + (temp1->array[i]>>4<<4) - (temp2->array[i-(temp1->length-temp2->length)]>>4<<4);
        if(difference->array[i]>160)
            difference->array[i] += 160, borrow = -1;
        LOG("minus:i: %d, 0x%x, 1:0x%x, 2:0x%x", i, difference->array[i], temp1->array[i], temp2->array[i-(temp1->length-temp2->length)]);
    }
    if(!borrow && temp1->length - temp2->length == 1)
        memcpy(difference->array, temp1->array, i+1);
    while(borrow && i>=0){   //在遍历完较小数的位数后,处理可能的借位
        difference->array[i] = temp1->array[i] - 1;
        if((difference->array[i]&15) == 15){
            LOG("carry1.0, %x", difference->array[i]);
            difference->array[i]=(difference->array[i]&240) - 7;
            LOG("carry1.1, %x", difference->array[i]);
            if(difference->array[i] == 249){//0xf9
                difference->array[i]=153;//0x99
                borrow=-1;
                LOG("carry2");
            }
            else
                borrow=0;
        }
        else
            borrow=0;
        i--;
    }
    LOG("BEFORE WHILE, i=%d", i);
    if(i>0){
        LOG("memcpy");
        memcpy(difference->array, temp1->array, i+1);
        difference->length = temp1->length;
    }    
    else{
        i=0;
        while(difference->array[0]==0){
            difference->array++;
            i++;
        }
        difference->length = temp1->length-i;
    }
    return difference;
}

//struct charnumber* powerCharNumber(struct charnumber* charnumber1, struct charnumber* pow){
//    struct charnumber* char1, sum=1;
//    int i;

//    char1 = malloc(struct charnumber);
//    char1->length = charnumber1->length;
//    char1->sign = charnumber1->sign;
//    char1->array = malloc(char1->length);
//    char1->pointerforfree = char1->array;
//    memcpy(char1->array, charnumber1->array, char1->length);
//    while(char1->length != 0){
//        if(char1->array[char1->length-1]&15 == 0){
//            if(char1->array[char1->length-1] == 0){
//                char1->array[char1->length-2]
//            }
//        }
//        sum=multiplyCharNumber(sum, charnumber1);
//        char1->length--;
//    }
//    return sum;
//}

超大整数运算算法——为RSA加密算法提供运算工具的更多相关文章

  1. 数据加密--详解 RSA加密算法 原理与实现

    RSA算法简介 RSA是最流行的非对称加密算法之一.也被称为公钥加密.它是由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adlema ...

  2. RSA加密算法的加密与解密

    转发原文链接:RSA加密算法加密与解密过程解析 1.加密算法概述 加密算法根据内容是否可以还原分为可逆加密和非可逆加密. 可逆加密根据其加密解密是否使用的同一个密钥而可以分为对称加密和非对称加密. 所 ...

  3. RSA加密算法 C++实现

    上信息安全课,老师布置了几个大作业,其中一个为RSA加密算法的实现,不能用Java写.出于兴趣,决定尝试.完成之后,为了便于查找,于是写下这篇文章,以备后续查看.也供大家一起学习,一起进步. 1.预备 ...

  4. 用实例讲解RSA加密算法(精)

    RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经 ...

  5. 轻松学习RSA加密算法原理

    转自:http://blog.csdn.net/sunmenggmail/article/details/11994013 http://blog.csdn.net/q376420785/articl ...

  6. RSA加密算法原理及RES签名算法简介

    第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一对密钥.一个是公钥,给A,B自己持有私钥.A使用B的公钥加密要加密发送的内容,然后B在通过自己的私钥解密 ...

  7. 轻松学习RSA加密算法原理 (转)

    轻松学习RSA加密算法原理 (转) http://blog.csdn.net/q376420785/article/details/8557266 http://www.ruanyifeng.com/ ...

  8. [转] 用实例给新手讲解RSA加密算法

    http://www.cfca.com.cn/zhishi/wz-012.htm PS: 通常公钥对数据加密,私钥对数据解密:私钥对数据签名,公钥对数据签名进行认证 RSA加密算法是最常用的非对称加密 ...

  9. 用实例给新手讲解RSA加密算法

    图为 RSA公开密钥算法的发明人,从左到右Ron Rivest, Adi Shamir, Leonard Adleman. 照片摄于1978年 RSA加密算法是最常用的非对称加密算法,CFCA在证书服 ...

随机推荐

  1. Hibernate中启用日志

    Problem How do you determine what SQL query is being executed by Hibernate? How can you see the Hibe ...

  2. 缓存应用--Memcached分布式缓存简介

    一.   什么是Memcached Memcached 是一个高性能的分布式内存 对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象 来减少读取数据库的次数,从而提供动态. ...

  3. 【ContestHunter】【弱省胡策】【Round3】(C)

    容斥原理+Fib Orz HE的神犇们 蒟蒻只能改出来第三题……实在太弱 官方题解:http://pan.baidu.com/s/1o6MdtQq fib的神奇性质……还有解密a[i]的过程……这里就 ...

  4. 【POJ】【2449】Remmarguts' Date

    K短路/A* 经(luo)典(ti) K短路题目= = K短路学习:http://www.cnblogs.com/Hilda/p/3226692.html 流程: 先把所有边逆向,做一遍dijkstr ...

  5. 剑指offer--面试题20

    题目:从外向里顺时针打印矩阵 做题心得:该题本质上并未考查复杂的数据结构及算法,而是考查了快速找规律的能力!!! 要想作出此题,必须先有绝对清晰的思路,否则越写越乱(因为涉及到很多的循环打印) 自己当 ...

  6. javascript版Ajax请求

    什么是Ajax请求,Ajax也就是“Asynchronous JavaScript and XML”(异步JavaScript和XML),无刷新数据读取.能减少流量的消耗,也提高了浏览的流畅性,给用户 ...

  7. themeforest 模板

    如果给个人或一个客户使用就购买Regular License 多个项目或多人就徐需要购买Extended License,然后看你买html模版还是wordpress模版了.html需要你自己会编程将 ...

  8. 在linux下安装eclipse 开发c语言程序

    一,下载jdk tar -xvzf jdk-8u45-linux-x64.tar.gz  //解压并安装jdk 二,修改环境配置变量 vim /home/woshareliu/.bashrc 加入如下 ...

  9. ARM系列产品

    ARM7系列 ARM9系列 ARM9E系列 ARM10E系列 SecurCore系列 Intel的StrongARM ARM11系列 Intel的Xscale 其中,ARM7.ARM9.ARM9E和A ...

  10. DMS平台从.NET 1.1升级到.NET 4.0的升级步骤

    1)复制新增的项目到4.0平台解决方案对应目录,添加到到解决方案中:2)合并公共文件(比如修改了FormMain主界面.基础类库.售后界面的修改)3)控件的修订(Dev少数属性可能需要手工调整为新的方 ...