大数分解的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;
    }
}
相关推荐
IT 行者5 小时前
Web逆向工程AI工具:JSHook MCP,80+专业工具让Claude变JS逆向大师
开发语言·javascript·ecmascript·逆向
程序员 沐阳6 小时前
JavaScript 内存与引用:深究深浅拷贝、垃圾回收与 WeakMap/WeakSet
开发语言·javascript·ecmascript
Mr_Xuhhh7 小时前
Java泛型进阶:从基础到高级特性完全指南
开发语言·windows·python
汀、人工智能7 小时前
[特殊字符] 第40课:二叉树最大深度
数据结构·算法·数据库架构·图论·bfs·二叉树最大深度
沉鱼.447 小时前
第十二届题目
java·前端·算法
He1955017 小时前
wordpress搭建块
开发语言·wordpress·古腾堡·wordpress块
老天文学家了8 小时前
蓝桥杯备战Python
开发语言·python
赫瑞8 小时前
数据结构中的排列组合 —— Java实现
java·开发语言·数据结构
大熊背8 小时前
ISP Pipeline中Lv实现方式探究之三--lv计算定点实现
数据结构·算法·自动曝光·lv·isppipeline
初夏睡觉8 小时前
c++1.3(变量与常量,简单数学运算详解),草稿公放
开发语言·c++