【Miracl用户手册学习】——【第一篇:因子分解算法】

一、分解因子算法——Pollard rho算法

Pollard-Rho算法是John Pollard发明的一种能快速找到大整数的一个非1、非自身的因子的算法。
参考1
参考2
参考3在这里插入图片描述

import math
from random import randint

def is_prime(number):
   if number > 1:
       if number == 2:
           return True
       if number % 2 == 0:
           return False
       for current in range(3, int(math.sqrt(number) + 1), 2):
           if number % current == 0:
               return False
       return True
   return False

def f(x,c,N):
   return (x*x +c)%N;

def Pollard_Rho(N):
   if N==4:
       return 2;
   if (is_prime(N)):
       return N;
   while 1:
       c = randint(1, N - 1);
       t = f(0,c,N)
       r = f(f(0,c,N),c,N)
       while (t != r):
           d = math.gcd(abs(t - r), N)
           if d>1:
               return d;
           t = f(t,c,N)
           r = f(f(r,c,N),c,N)
print(Pollard_Rho(7171))
import numpy as np
import matplotlib.pyplot as plt
x=0
c=24
N=9400
num = []
num.append(x)
for i in range(130):
   x=(x*x+c)%N
   num.append(x)

plt.scatter(range(131), num)
plt.plot([0,9.5],[9.5,0],linewidth = '0.5',color='#000000')
plt.legend()
plt.show()

二、brute force to factor numbers

遵循原理:任意整数可以唯一标识成素数的积

#include <iostream>
#include<big.h>
using namespace std;
extern "C"
{
#include "miracl.h"
#include "mirdef.h"

}
#define LIMIT 15000

int main()
{ /* find factors by brute force division */
	int n, p;

#ifdef MR_NOFULLWIDTH
	miracl *mip = mirsys(50, MAXBASE);
#else  
	miracl *mip = mirsys(50, 0);
#endif

	char stack_mem[mr_big_reserve(2, 50)];  // 2 bigs, 4 bytes per big...
	big x, y;

	memset(stack_mem, 0, mr_big_reserve(2, 50));
	x = mirvar_mem(stack_mem, 0);
	y = mirvar_mem(stack_mem, 1);

	/* This is an example of allocating bigs x and y from the stack rather than
	   from the heap. The "50" should be the same as that used in the prior call
	   to mirsys(.), and MUST be a constant. There is never a need to explicitly
	   delete bigs allocated from the stack, via a call to mirkill(). Therefore
	   do not use for sensitive data as these bigs are not erased, unless you
	   do it yourself via a call to zero(.)

	   Allocation from the stack is not particularly recommended, but could be
	   faster if bigs are not too big, and are required as temporary variables
	   in an often called subroutine. Allocating from the stack also avoids the
	   possibility of memory leaks.

	   NOTE: A big allocated from the stack has a random initial value

	*/
	gprime(LIMIT);
	printf("input number to be factored\n");
	cinnum(x, stdin);
	if (isprime(x))
	{
		printf("this number is prime!\n");
		return 0;
	}
	n = 0;
	p = mip->PRIMES[0];
	printf("factors are \n");
	forever //#define forever for(;;)   
	{ /* try division by each prime in turn */
		if (subdiv(x,p,y) == 0)
		{ /* factor found */
			copy(y,x);
			printf("prime factor     ");
			printf("%d\n",p);
			if (size(x) == 1) return 0;
			continue;
		}
		if (size(y) <= p)
		{ /* must be prime */
			printf("prime factor     ");
			cotnum(x,stdout);
			return 0;
		}
		p = mip->PRIMES[++n];
		if (p == 0) break;
	}
	if (isprime(x)) printf("prime factor     ");
	else            printf("composite factor ");
	cotnum(x, stdout);
	return 0;
}

gprime

在这里插入图片描述

isprime

在这里插入图片描述

size*

在这里插入图片描述

subdiv

在这里插入图片描述

三、brute force to factor numbers

#include <iostream>
#include<big.h>
using namespace std;
extern "C"
{
#include "miracl.h"
#include "mirdef.h"

}
/*
 *   Program to factor big numbers using Brent-Pollard method.
 *   See "An Improved Monte Carlo Factorization Algorithm"
 *   by Richard Brent in BIT Vol. 20 1980 pp 176-184
 *
 */

#include <stdio.h>
#ifdef MR_STATIC
#include <string.h>
#endif

#define mr_min(a,b) ((a) < (b)? (a) : (b))

int main()
{  /*  factoring program using Brents method */
	long k, r, i, m, iter;
	big x, y, z, n, q, ys, c3;
#ifndef MR_STATIC
	miracl *mip = mirsys(16, 0);         /* if allocating from the heap, specify size of bigs here */
	char *mem = (char *)memalloc(7);            /* allocate and clear memory from the heap for 7 bigs     */
#else
	miracl *mip = mirsys(MR_STATIC, 0);  /* If allocating from the stack, size of bigs is pre-defined */
	char mem[MR_BIG_RESERVE(7)];      /* reserve space on the stack for 7 bigs ...  */
	memset(mem, 0, MR_BIG_RESERVE(7));  /* ... and clear this memory */
#endif

	x = mirvar_mem(mem, 0);              /* 7 bigs have index from 0-6  */
	y = mirvar_mem(mem, 1);
	ys = mirvar_mem(mem, 2);
	z = mirvar_mem(mem, 3);
	n = mirvar_mem(mem, 4);
	q = mirvar_mem(mem, 5);
	c3 = mirvar_mem(mem, 6);
	convert(3, c3);

	printf("input number to be factored\n");
	cinnum(n, stdin);
	if (isprime(n))
	{
		printf("this number is prime!\n");
		return 0;
	}
	m = 10L;
	r = 1L;
	iter = 0L;
	do
	{
		printf("iterations=%5ld", iter);
		convert(1, q);
		do
		{
			copy(y, x);
			for (i = 1L; i <= r; i++)
				mad(y, y, c3, n, n, y);
			k = 0;
			do
			{
				iter++;
				if (iter % 10 == 0) printf("\b\b\b\b\b%5ld", iter);
				fflush(stdout);
				copy(y, ys);
				for (i = 1L; i <= mr_min(m, r - k); i++)
				{
					mad(y, y, c3, n, n, y);
					subtract(y, x, z);
					mad(z, q, q, n, n, q);
				}
				egcd(q, n, z);
				k += m;
			} while (k < r && size(z) == 1);
			r *= 2;
		} while (size(z) == 1);
		if (mr_compare(z, n) == 0) do
		{ /* back-track */
			mad(ys, ys, c3, n, n, ys);
			subtract(ys, x, z);
		} while (egcd(z, n, z) == 1);
		if (!isprime(z))
			printf("\ncomposite factor ");
		else printf("\nprime factor     ");
		cotnum(z, stdout);
		if (mr_compare(z, n) == 0) return 0;
		divide(n, z, n);
		divide(y, n, n);
	} while (!isprime(n));
	printf("prime factor     ");
	cotnum(n, stdout);
#ifndef MR_STATIC
	memkill(mem, 7);                  /* delete all 7 bigs */
#else
	memset(mem, 0, MR_BIG_RESERVE(7)); /* clear memory used for bigs */
#endif
	return 0;
}

memset(b, 0, sizeof(b))

memset是个函数,它在string.h头文件中有声明。它有三个参数,一是所要set的首地址,二是set的值,三是set的字节数。

b大部分情况下是个数组,因为数组在传参时能自动转成指向数组的首元素的指针;如果不是数组,应该写成memset(&b, 0, sizeof(b));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值