大数分解的Shor算法-C#

看代码吧,没有太多要说的

cs 复制代码
using System.Numerics;
using System.Security.Cryptography;

namespace ShorAlgorithm;

class Program
{
    /*********************************************************************
     *	shor.cc -- Use Shor's Algorithm
     *		to factor a large BigInteger
     * ChangeLog:
     *  970225 -- Created by Paul Herman <a540pau@pslc.ucla.edu>
    **********************************************************************/
    static BigInteger GenerateRandomOddBigInteger(int count = 8)
    {
        if (count <= 0) throw new ArgumentException(null, nameof(count));
        // 创建一个RandomNumberGenerator实例
        using var generator = RandomNumberGenerator.Create();
        // 生成一个足够长的字节数组,例如16字节(128位)
        var randomBytes = new byte[count]; // 可以根据需要增加字节数以生成更大的数
        generator.GetBytes(randomBytes);
        randomBytes[0] |= 1; // 确保生成的数是奇数,以增加找到因子的概率
        // 将字节数组转换为BigInteger
        // 注意:这里使用了BigEndianBitConverter,因为BigInteger期望高位在前(大端格式)
        randomBytes[^1] &= 0x7f; // 确保生成的数是正数
        return new (randomBytes);
    }

    /********************************************************************
    /*  Period:  This computes the size of the group generated by a mod n
    /*           i.e. |<a>|
    /********************************************************************/
    static long GetCycle(BigInteger a, BigInteger n)
    {
        var count = 1L;

        Parallel.For(1L, long.MaxValue, (i, state) =>
        {
            if (BigInteger.ModPow(a, i, n) == BigInteger.One)
            {
                count = i;
                state.Stop();
            }
        });

        return count;
    }

    /************************************************************************************
    /*  ShorFactor:  Finds a factor of n by looking at the group generated
    /*               by <a> mod n.  Let t = |<a>|/2  .  Check to see if
    /*               t +/- 1 and n have a common factor.  If not, try another a
    /************************************************************************************/

    static BigInteger ShorFactor(BigInteger n, BigInteger a, long retries = 4096, bool use_cycle = false)
    {
        BigInteger t1, t2, f1, f2, r;
        int j;

        a = a.IsZero ? GenerateRandomOddBigInteger(n.GetByteCount()) : a;

        while (true)
        {
            j = 2;
            //我在这里改为随机化

            r = use_cycle ? GetCycle(a, n) : BigInteger.ModPow(a, j, n);
            for (; ; j++)
            {
                //随机数a是n的因子
                f1 = BigInteger.GreatestCommonDivisor(a, n);
                if (f1 == n) goto tail;
                if (f1 != BigInteger.One) return f1;
                //t1和t2分别是a^((a^j mod n)/2) mod n的+1和-1
                t1 = BigInteger.ModPow(a, (r >> 1), n);
                t1 += 1;
                t2 = t1 - 2;

                //t1=(a^(r/2) mod n) + 1
                //t2=(a^(r/2) mod n) - 1

                //测试t1
                f1 = BigInteger.GreatestCommonDivisor(t1, n);
                if (f1 != BigInteger.One && f1 != n)
                    return f1;
                //测试t2
                f2 = BigInteger.GreatestCommonDivisor(t2, n);
                if (f2 != BigInteger.One && f2 != n)
                    return f2;
                //如果t1和t2都没有找到因子,那么就换一个a继续试s
                a += 1;
                if (--retries == 0)
                    return n;
                //计算a^j mod n,求r的下一个数值
                r = BigInteger.ModPow(a, j, n);
                //如果r为负数,说明a^j mod n的结果是负数,这不应该发生,因为模运算的结果应该在0到n-1之间
                if (r < 0) goto tail;
            }
            tail:
                a = GenerateRandomOddBigInteger(n.GetByteCount());
        }
    }
    public static bool IsPrime(BigInteger number)
    {
        // 小于等于1的数不是质数
        if (number <= 1)
            return false;

        // 2 是质数
        if (number == 2)
            return true;

        // 偶数(除了2)不是质数
        if (number.IsEven)
            return false;

        // 使用试除法检查从3到√n的所有奇数
        BigInteger sqrt = Sqrt(number);
        for (BigInteger i = 3; i <= sqrt; i += 2)
        {
            if (number % i == 0)
                return false;
        }

        return true;
    }

    // 计算 BigInteger 的平方根
    private static BigInteger Sqrt(BigInteger number)
    {
        if (number == 0)
            return 0;

        BigInteger x = number;
        BigInteger y = (x + 1) / 2;

        while (y < x)
        {
            x = y;
            y = (x + number / x) / 2;
        }

        return x;
    }
    static BigInteger default_value = 70191551;
    static int Main(string[] args)
    {
        default_value = GenerateRandomOddBigInteger(32);

        var n = args.Length > 0
            ? BigInteger.TryParse(args[0], out var v)
            ? v : default_value
            : default_value
            ;
        var u = n;
        List<BigInteger> factors = [];
        Console.WriteLine($"Factoring n = {n}:");
        var i = 1;
        var retries = n.GetByteCount() * 4096;
        while (n != BigInteger.One)
        {
            var factor = ShorFactor(n, BigInteger.Zero, retries);
            Console.WriteLine($"Found factor{i} = {factor}, IsPrime={IsPrime(factor)}");
            n /= factor;
            i++;
            factors.Add(factor);
        }
        Console.WriteLine("Factorization complete.");
        var s = factors.Aggregate((a, b) => a * b);
        if (s == u)
        {
            Console.WriteLine("Verification: OK.");
        }
        else
        {
            Console.WriteLine("Verification: Fail.");
        }
        return 0;
    }
}
相关推荐
问好眼1 小时前
《算法竞赛进阶指南》0x01 位运算-3.64位整数乘法
c++·算法·位运算·信息学奥赛
yyjtx1 小时前
DHU上机打卡D31
开发语言·c++·算法
GEO行业研究员1 小时前
《认知锚定与路径锁死:基于爱搜光年模型的AI决策链条风险放大机制监测》
人工智能·算法·ai搜索优化·geo优化·医疗geo·医疗geo优化
wefg12 小时前
【算法】单调栈和单调队列
数据结构·算法
岛雨QA2 小时前
图「Java数据结构与算法学习笔记12」
数据结构·算法
rit84324992 小时前
全变分正则化图像去噪的MATLAB实现
开发语言·matlab
勇往直前plus2 小时前
python格式化字符串
开发语言·前端·python
岛雨QA2 小时前
多路查找树「Java数据结构与算法学习笔记11」
数据结构·算法
_Li.2 小时前
Simulink - 6DOF (Euler Angles)
人工智能·算法·机器学习·游戏引擎·cocos2d