openssl库中BIGNUM的使用

随机数

加减乘除

取模

指数

 

#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/err.h>

void bn_printf(BIGNUM * a, int n)
{
	printf("0x");
	BN_print_fp(stdout, a);
	if (n)
		printf("\n");
}

void bn_hex_printf(BIGNUM * a)
{
	char *p = BN_bn2hex(a);
	printf("0x%s\n", p);
	OPENSSL_free(p);
}

void bn_dec_printf(BIGNUM * a)
{
	char *p = BN_bn2dec(a);
	printf("%s\n", p);
	OPENSSL_free(p);
}

int main(int argc, char *argv[])
{
	int bits = 3;

	if (argc > 1) {
		bits = atoi(argv[1]);
	}
	if (bits <= 0) {
		bits = 8;
	}
	printf("bits: %d\n", bits);

	BN_CTX *ctx;
	BIGNUM a, b, c, d;

	ctx = BN_CTX_new();
	if (ctx == NULL)
		exit(1);

	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
	BN_init(&d);

	BN_rand(&a, bits, 1, 1);
	printf("BN_rand a: ");
	bn_printf(&a, 1);
	bn_hex_printf(&a);
	bn_dec_printf(&a);

	BN_add_word(&a, 1);
	printf("BN_add_word a + 1\n");
	bn_printf(&a, 1);

	BN_free(&a);
	BN_init(&a);

	BN_rand(&a, bits, 1, 0);
	printf("BN_rand a: ");
	bn_printf(&a, 1);

	BN_rand(&b, bits, 0, 1);
	printf("BN_rand b: ");
	bn_printf(&b, 1);

	BN_add(&c, &a, &b);
	printf("BN_add a + b\n");
	bn_printf(&a, 0);
	printf(" + ");
	bn_printf(&b, 0);
	printf(" = ");
	bn_printf(&c, 1);

	BN_sub(&c, &a, &b);
	printf("BN_sub a - b\n");
	bn_printf(&a, 0);
	printf(" - ");
	bn_printf(&b, 0);
	printf(" = ");
	bn_printf(&c, 1);

	BN_mul(&c, &a, &b, ctx);
	printf("BN_mul a * b\n");
	bn_printf(&a, 0);
	printf(" * ");
	bn_printf(&b, 0);
	printf(" = ");
	bn_printf(&c, 1);

	BN_div(&d, &c, &a, &b, ctx);
	printf("BN_div a / b\n");
	bn_printf(&a, 0);
	printf(" / ");
	bn_printf(&b, 0);
	printf(" = ");
	bn_printf(&d, 1);
	printf("remainder ");
	bn_printf(&c, 1);

	BN_mod(&c, &a, &b, ctx);
	printf("BN_mod a %% b\n");
	bn_printf(&a, 0);
	printf(" %% ");
	bn_printf(&b, 0);
	printf(" = ");
	bn_printf(&c, 1);

	BN_exp(&c, &a, &b, ctx);
	printf("BN_exp a ^ b\n");
	bn_printf(&a, 0);
	printf(" ^ ");
	bn_printf(&b, 0);
	printf(" = ");
	if (BN_num_bits(&c) < 64 * 8) {
		bn_printf(&c, 1);
	} else {
		printf("BN_num_bits(c) %d too long, not print\n",
		       BN_num_bits(&c));
	}

	BN_set_word(&a, 100);
	printf("BN_set_word a: ");
	bn_printf(&a, 1);

	bn_printf(&a, 0);
	if (BN_is_word(&a, 100)) {
		printf(" is 100\n");
	} else {
		printf(" is not 100\n");
	}

	BN_set_negative(&a, 1);
	printf("BN_set_negative a: ");
	bn_dec_printf(&a);

	BN_free(&a);
	BN_init(&a);

	BN_generate_prime_ex(&a, bits, 1, NULL, NULL, NULL);
	printf("BN_generate_prime_ex a: ");
	bn_printf(&a, 1);

	bn_printf(&a, 0);
	if (1 == BN_is_prime_ex(&a, BN_prime_checks, NULL, NULL)) {
		printf(" is prime\n");
	} else {
		printf(" is not prime\n");
	}

	BN_add_word(&a, 2);
	bn_printf(&a, 0);
	if (1 == BN_is_prime_ex(&a, BN_prime_checks, NULL, NULL)) {
		printf(" is prime\n");
	} else {
		printf(" is not prime\n");
	}

	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);

	BN_CTX_free(ctx);

	return 0;
}


 

运行结果

 

$ gcc -Wall -lcrypto bn.c


$ ./a.out 5                                             
bits: 5
BN_rand a: 0x19
0x19
25
BN_add_word a + 1
0x1A
BN_rand a: 0x1E
BN_rand b: 0x1D
BN_add a + b
0x1E + 0x1D = 0x3B
BN_sub a - b
0x1E - 0x1D = 0x1
BN_mul a * b
0x1E * 0x1D = 0x366
BN_div a / b
0x1E / 0x1D = 0x1
remainder 0x1
BN_mod a % b
0x1E % 0x1D = 0x1
BN_exp a ^ b
0x1E ^ 0x1D = 0x4EC8A7BC9DC1FCCECDF11AC97979E0000000
BN_set_word a: 0x64
0x64 is 100
BN_set_negative a: -100
BN_generate_prime_ex a: 0x8C27
0x8C27 is prime
0x8C29 is not prime


$ ./a.out 16
bits: 16
BN_rand a: 0xD3C5
0xD3C5
54213
BN_add_word a + 1
0xD3C6
BN_rand a: 0xCDE5
BN_rand b: 0xB79B
BN_add a + b
0xCDE5 + 0xB79B = 0x18580
BN_sub a - b
0xCDE5 - 0xB79B = 0x164A
BN_mul a * b
0xCDE5 * 0xB79B = 0x93AB5CA7
BN_div a / b
0xCDE5 / 0xB79B = 0x1
remainder 0x164A
BN_mod a % b
0xCDE5 % 0xB79B = 0x164A
BN_exp a ^ b
0xCDE5 ^ 0xB79B = BN_num_bits(c) 737278 too long, not print
BN_set_word a: 0x64
0x64 is 100
BN_set_negative a: -100
BN_generate_prime_ex a: 0xDEA7
0xDEA7 is prime
0xDEA9 is not prime


 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于斐波那契数列的增长速度非常快,计算第1亿位的斐波那契数是非常耗时的,需要用到高精度计算。以下是一个使用C语言实现高精度计算的斐波那契数列第1亿位的算法代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LEN 1000000 // 最大位数 typedef struct BigNum { int len; int num[MAX_LEN]; } BigNum; BigNum* createBigNum(int len) { BigNum* bn = (BigNum*)malloc(sizeof(BigNum)); memset(bn->num, 0, sizeof(bn->num)); bn->len = len; return bn; } void printBigNum(BigNum* bn) { int i; for (i = bn->len - 1; i >= 0; i--) { printf("%d", bn->num[i]); } } BigNum* addBigNum(BigNum* a, BigNum* b) { BigNum* c = createBigNum(a->len > b->len ? a->len + 1 : b->len + 1); int i; for (i = 0; i < c->len; i++) { c->num[i] += a->num[i] + b->num[i]; if (c->num[i] >= 10) { c->num[i] -= 10; c->num[i+1]++; } } while (c->len > 1 && c->num[c->len-1] == 0) { c->len--; } return c; } BigNum* fib(int n) { BigNum* a = createBigNum(1); BigNum* b = createBigNum(1); BigNum* c; a->num[0] = 0; b->num[0] = 1; int i; for (i = 2; i <= n; i++) { c = addBigNum(a, b); a = b; b = c; } return b; } int main() { BigNum* bn = fib(100000000); printBigNum(bn); return 0; } ``` 这个算法使用了高精度计算来计算斐波那契数列第1亿位,因此需要使用额外的数据结构(BigNum)来进行高精度计算。在算法,我们首先创建一个BigNum结构体来存储高精度数字,然后实现了三个基本的高精度计算函数:createBigNum、printBigNum和addBigNum。createBigNum用于创建一个新的BigNum结构体,printBigNum用于将BigNum结构体的数字打印出来,addBigNum用于实现高精度加法。 接着,我们使用fib函数来计算第1亿位的斐波那契数,其使用了两个BigNum结构体a和b来存储前两个斐波那契数,然后使用循环结构依次计算每一个斐波那契数,直到计算到第1亿位为止。 最后,在主函数调用fib函数来计算第1亿位的斐波那契数,并使用printBigNum将结果打印出来。由于计算量非常大,运行时间会非常长。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值