分析midea0978的《一个C#算法分析求解》(三)(完)

简介:

六、逆算准备
根据J和K的关系,很容易就可以根据数组个数计算出实际字符个数。
建立相应的字符对象数组,并使用密码表中不存在的字符(这里是空格符)初始化。
为Bts属性指定一个和原数组个数一样的全0数组,用于存放结果,
而Bts2中放置原数组。因此,我们所要做的事情就是,对于这个字符对象数组中的每一个对象,
找到一个合适的N,使得Bts中的数据和Bts2一样。这个时候每个字符对象对应的字符就是密码表中的第N个字符。
ReCalc中建立了一个列表数组lists,用于存放每个字节受哪些字符对象“控制”(由该字符对象参数生成)。

七、开始逆算
准备好上面的工作后,就可以开始逆算了。
对于字节数组中start位置的字节,它的控制列表为list=lists[start],
也就是说,所有影响这个位置的字节码生成的字符对象ID,都存放在这个list中。
我们只需要遍历这个list中每一个字符对象的所有NList可能,就可以计算出所有Bts[start]的可能,
取其中Bts[start]=Bts2[start]的就是了。
因为J的关系,list中最大的元素个数是3,所以,最多只需要3层循环。
此外,还有一个技巧需要说明,最后一个字节的控制列表只有一个字符对象,并且一定是最后的那个,这些从
J和K那里可以得知。

每一次NList的循环之前,都需要先备份K和M处的字节数据,以备下一轮循环前还原。
循环把NList的每一个N可能赋值给这个字符对象的N,然后执行Cal计算字节数据。
循环内部再嵌套控制列表list中的下一个字符对象。
在最里面一层循环里面,对比Bts[start]是否等于Bts2[start],
如果相等,表明该层控制列表各字符对象的N值符合要求(但不是唯一的可能,还可能有别的组合)。
此时,就可以进入start-1层的计算了,该是递归上场的时候了。

且慢,在这之前,还需要做一些准备工作。
这一层已经计算好的字符对象,在下一层的时候可不能重新参与计算,否则就会影响这一层已经计算好的值了。
根据递归原则,我们应该“锁定”这些对象,不允许子递归修改这些对象,
子递归只能通过循环控制列表中的其它对象来“凑”出一个合适的Bts(start)。

八、总结
整个递归算法是深度搜索算法。由于字符与字符之前有相互关系,所以必须是深度搜索,
但又因为这个关系只存在相邻字符之间,所以深度搜索不必每次“到底”。
运算速度还不错,所以就不做性能优化了。

历时24小时左右(20+4,中间小睡了一会)
大石头
QQ:99363590
Email:gxuhy#21cn.com
http://www.nnhy.org
2007-12-02 01:04
C#逆向算法分析

  1
  2          /// <summary>
  3        /// 搜索
  4        /// </summary>
  5        /// <param name="ts"></param>
  6        /// <param name="lists"></param>
  7        /// <param name="start"></param>
  8        /// <returns></returns>

  9          public  static Boolean Find(CharObject[] ts, List<Int32> locks, List<Int32>[] lists, Int32 start)
 10          {
 11            Console.WriteLine(new String(' ', 12 - start) + "第{0}层", start.ToString());
 12
 13            //结束条件
 14            if (start < 0)
 15            {
 16                StringBuilder sb = new StringBuilder();
 17                for (int i = 0; i < ts.Length; i++)
 18                {
 19                    if (ts[i] == nullbreak;
 20                    sb.Append(ts[i].C);
 21                }

 22                Console.WriteLine(sb.ToString());
 23                //如果需要取得所有结果,只需要把下面改成return false;
 24                //return false;
 25                return true;
 26            }

 27
 28            //递归过程
 29            List<Int32> list = new List<int>();
 30            //排除锁定项
 31            foreach (Int32 t in lists[start])
 32            {
 33                if (!locks.Contains(t)) list.Add(t);
 34            }

 35            if (list.Count < 1) return true;
 36            list.Sort(IntSort);
 37
 38            CharObject A = ts[list[0]];
 39            Byte[] Bts = A.Bts;
 40            Byte[] Bts2 = A.Bts2;
 41
 42            //处理start以下的字节
 43            //上层递归最多到达start处,而本层就要用到start-1了,
 44            //处理一下,以免别的子递归曾经修改过start-1
 45            if (start > 0) Bts[start - 1] = 0;
 46
 47            //备份A控制的两个字节,而不一定是Bts[start]和Bts[start-1]
 48            Byte[] temp_a = new Byte[2];
 49            temp_a[0] = Bts[A.K];
 50            temp_a[1] = Bts[A.M];
 51            foreach (Int32 a in A.NList)
 52            {
 53                Bts[A.K] = temp_a[0];
 54                Bts[A.M] = temp_a[1];
 55                A.N = a;
 56                A.Cal();
 57                if (list.Count < 2)
 58                {
 59                    if (Bts[start] != Bts2[start]) continue;
 60                    locks.Add(A.ID);
 61                    if (Find(ts, locks, lists, start - 1)) return true;
 62                    locks.Remove(A.ID);
 63                    continue;
 64                }

 65                CharObject B = ts[list[1]];
 66                Byte[] temp_b = new Byte[2];
 67                temp_b[0] = Bts[B.K];
 68                temp_b[1] = Bts[B.M];
 69                foreach (Int32 b in B.NList)
 70                {
 71                    Bts[B.K] = temp_b[0];
 72                    Bts[B.M] = temp_b[1];
 73                    B.N = b;
 74                    B.Cal();
 75                    if (list.Count < 3)
 76                    {
 77                        //有限个数控制,马上判断
 78                        if (Bts[start] != Bts2[start]) continue;
 79                        locks.Add(A.ID);
 80                        locks.Add(B.ID);
 81                        if (Find(ts, locks, lists, start - 1)) return true;
 82                        locks.Remove(A.ID);
 83                        locks.Remove(B.ID);
 84                        continue;
 85                    }

 86                    CharObject C = ts[list[2]];
 87                    Byte[] temp_c = new Byte[2];
 88                    temp_c[0] = Bts[C.K];
 89                    temp_c[1] = Bts[C.M];
 90                    foreach (Int32 c in C.NList)
 91                    {
 92                        Bts[C.K] = temp_c[0];
 93                        Bts[C.M] = temp_c[1];
 94                        C.N = c;
 95                        C.Cal();
 96                        //有限个数控制,马上判断
 97                        if (Bts[start] != Bts2[start]) continue;
 98                        locks.Add(A.ID);
 99                        locks.Add(B.ID);
100                        locks.Add(C.ID);
101                        if (Find(ts, locks, lists, start - 1)) return true;
102                        locks.Remove(A.ID);
103                        locks.Remove(B.ID);
104                        locks.Remove(C.ID);
105                    }

106                    Bts[C.K] = temp_c[0];
107                    Bts[C.M] = temp_c[1];
108                }

109                Bts[B.K] = temp_b[0];
110                Bts[B.M] = temp_b[1];
111            }

112            Bts[A.K] = temp_a[0];
113            Bts[A.M] = temp_a[1];
114            return false;
115        }

116

 

我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
分类: 逆向

本文转自大石头博客园博客,原文链接:http://www.cnblogs.com/nnhy/archive/2007/12/02/979777.html,如需转载请自行联系原作者
目录
相关文章
|
3月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
96 3
|
8天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
27 11
|
10天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
41 10
|
5天前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
14天前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
25 6
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
67 1
|
3月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
3月前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
4月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
80 1
|
3月前
|
算法
PID算法原理分析及优化
【10月更文挑战第6天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。

热门文章

最新文章