大数分解的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;
    }
}
相关推荐
l1t1 分钟前
与系统库同名python脚本文件引起的奇怪错误及其解决
开发语言·数据库·python
Jackey_Song_Odd6 分钟前
Part 1:Python语言核心 - 内建数据类型
开发语言·python
切糕师学AI13 分钟前
编程语言 Erlang 简介
开发语言·erlang
小范自学编程13 分钟前
算法训练营 Day37 - 动态规划part06
算法·动态规划
sycmancia14 分钟前
C++——C++中的类型识别
开发语言·c++
还是大剑师兰特15 分钟前
Vue3 按钮切换示例(启动 / 关闭互斥显示)
开发语言·javascript·vue.js
星空露珠18 分钟前
迷你世界UGC3.0脚本Wiki角色模块管理接口 Actor
开发语言·数据库·算法·游戏·lua
我星期八休息18 分钟前
深入理解哈希表
开发语言·数据结构·c++·算法·哈希算法·散列表
一叶落43825 分钟前
LeetCode 54. 螺旋矩阵(C语言详解)——模拟 + 四边界收缩
java·c语言·数据结构·算法·leetcode·矩阵
寻寻觅觅☆34 分钟前
东华OJ-进阶题-19-排队打水问题(C++)
开发语言·c++·算法