大数分解的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;
    }
}
相关推荐
黄敬峰13 分钟前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六5 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术5 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize6 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考20 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队1 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl