⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ubiginteger.cs

📁 使用非对成RSA算法的序列号验证基础库
💻 CS
📖 第 1 页 / 共 4 页
字号:
using System;
using System.Text;

#region 版权声明
///
/// 版权所有(C)2005,2006  作者:漆巧林。保留所有权利, davidqql@gmail.com, davidqql@hotmail.com
/// 
/// 作者不对本代码提供任何保证,因此,对于使用该代码带来的损害或者潜在的损害,作者不承担责任。
/// 在满足如下的条件下,你可以自由使用该代码:
/// 1. 非商业应用
/// 2. 保留本版权声明
/// 要进行商业应用,必须得到作者的书面许可。
/// 你可以修改和自由发布本代码,条件是保留前述的版权声明。
/// 
#endregion

namespace BizSecurity
{
	/// <summary>
	/// UBigInteger :无符号大整数,其长度最多为2^31个位(以0x100000000进制计算)。
	/// </summary>
	public class UBigInteger
	{
		#region 常量区
		public static readonly Char[] LowerHexCharMapping = 
		{
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
		};

		public static readonly Char[] UpperHexCharMapping = 
		{
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
		};

		public static readonly uint[] PrimeTable =
		{
			3,    5,    7,    11,   13,   17,   19,   23,   29,   31,
			37,   41,   43,   47,   53,   59,   61,   67,   71,   73,
			79,   83,   89,   97,   101,  103,  107,  109,  113,  127,
			131,  137,  139,  149,  151,  157,  163,  167,  173,  179,
			181,  191,  193,  197,  199,  211,  223,  227,  229,  233,
			239,  241,  251,  257,  263,  269,  271,  277,  281,  283,
			293,  307,  311,  313,  317,  331,  337,  347,  349,  353,
			359,  367,  373,  379,  383,  389,  397,  401,  409,  419,
			421,  431,  433,  439,  443,  449,  457,  461,  463,  467,
			479,  487,  491,  499,  503,  509,  521,  523,  541,  547,
			557,  563,  569,  571,  577,  587,  593,  599,  601,  607,
			613,  617,  619,  631,  641,  643,  647,  653,  659,  661,
			673,  677,  683,  691,  701,  709,  719,  727,  733,  739,
			743,  751,  757,  761,  769,  773,  787,  797,  809,  811,
			821,  823,  827,  829,  839,  853,  857,  859,  863,  877,
			881,  883,  887,  907,  911,  919,  929,  937,  941,  947,
			953,  967,  971,  977,  983,  991,  997,  1009, 1013, 1019,
			1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087,
			1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153,
			1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229,
			1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297,
			1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381,
			1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453,
			1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523,
			1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597,
			1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663,
			1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741,
			1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823,
			1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901,
			1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993,
			1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063,
			2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131,
			2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221,
			2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293,
			2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371,
			2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437,
			2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539,
			2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621,
			2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689,
			2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749,
			2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833,
			2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909,
			2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001,
			3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083,
			3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187,
			3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259,
			3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343,
			3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433,
			3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517,
			3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581,
			3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659,
			3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733,
			3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823,
			3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911,
			3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001
		};
		#endregion

		static Random random;

		private int nCapacity;					// 最大容量
		private int nLength;					// 长度(按2^32进制计算)
		private uint[] values;					// 各个数字位取值

		static UBigInteger()
		{
			random = new Random();
		}

		/// <summary>
		/// 默认构造函数:创建一个1024位的无符号整数
		/// </summary>
		public UBigInteger()
			: this(32)
		{
		}

		/// <summary>
		/// 指定最大容量构造无符号大整数
		/// </summary>
		/// <param name="capacity">指定的容量</param>
		public UBigInteger(int capacity)				// 指定容量的构造函数
		{
			nLength = 0;
			nCapacity = capacity;
			values = new uint[nCapacity];
		}

		/// <summary>
		/// 从其他实例构造副本实例
		/// </summary>
		/// <param name="other">其他大整数实例</param>
		public UBigInteger(UBigInteger other)		// 从其他实例构造
			:this(other.nCapacity)
		{
			nLength = other.nCapacity - other.nLength;
			while(nLength < nCapacity)
			{
				values[nLength] = other.values[nLength];
				nLength ++;
			}
			nLength = other.nLength;
		}

		/// <summary>
		/// 判断与一个object对象是否相等,重载object的Equals
		/// </summary>
		/// <param name="obj">用于比较的对象</param>
		/// <returns>如果两个对象相等,返回真值,否则返回假</returns>
		public override bool Equals(object obj)
		{
			if(obj is UBigInteger)
			{
				return this == (UBigInteger)obj;
			}
			return false;
		}

		/// <summary>
		/// 重载object类的HashCode
		/// </summary>
		/// <returns>返回基类的HashCode</returns>
		public override int GetHashCode()
		{
			return base.GetHashCode ();
		}

		#region 属性区
		/// <summary>
		/// 获取当前大整数长度(以0x100000000进制计算)
		/// </summary>
		public int Length
		{
			get { return nLength; }
		}

		/// <summary>
		/// 获取二进制位数长度
		/// </summary>
		public int BitLength
		{
			get
			{
				if(nLength == 0)
					return 0;
				uint highest = values[nCapacity - nLength];

				int bits = nLength * 32;

				uint bit = 0xFF000000;
				while(bit > 0 && (highest & bit)==0)
				{
					bit >>= 8;
					bits -= 8;
				}
				return bits;
			}
		}

		/// <summary>
		/// 获取大整数的当前最大容量
		/// </summary>
		public int Capacity
		{
			get { return nCapacity; }
		}

		/// <summary>
		/// 设置当前大整数实例,拷贝其他实例的数据
		/// </summary>
		public UBigInteger Item
		{
			set
			{
				if(nCapacity < value.nCapacity)
				{
					nCapacity = value.nCapacity;
					values = new uint[nCapacity];
				}

				int nOther = value.nCapacity;
				int nThis = nCapacity;

				int nNumber = value.nLength;
				while(nNumber-- > 0)
				{

					values[--nThis] = value.values[--nOther];
				}
				while(nThis > 0)
				{
					values[--nThis] = 0;
				}
				nLength = value.nLength;
			}
		}

		#endregion

		#region 重载运算符区
		/// <summary>
		/// operator +,两个大整数相加
		/// </summary>
		/// <param name="augend">被加数</param>
		/// <param name="addend">加数</param>
		/// <returns>返回相加之后的结果,不改变加数和被加数的值</returns>
		public static UBigInteger operator +(UBigInteger augend, UBigInteger addend)
		{
			int maxLength;
			if(augend.nLength > addend.nLength)
			{
				maxLength = augend.nLength >= augend.nCapacity ? augend.nCapacity + 1 : augend.nCapacity;
			}
			else
			{
				maxLength = addend.nLength >= addend.nCapacity ? addend.nCapacity + 1 : addend.nCapacity;
			}

			UBigInteger result = new UBigInteger(maxLength);

			ulong sum;
			uint carry = 0;
			int nAugend = augend.nLength;
			int nAddend = addend.nLength;

			int nStartAugend = augend.nCapacity;
			int nStartAddend = addend.nCapacity;

			while((nAugend > 0) && (nAddend > 0))
			{
				sum = augend.values[--nStartAugend];
				sum += addend.values[--nStartAddend];
				sum += carry;
				result.values[--maxLength] = (uint)sum;
				carry = (uint)(sum >> 32);

				nAugend --;
				nAddend --;
			}
			while(nAddend > 0)
			{
				sum = addend.values[--nStartAddend];
				sum += carry;
				result.values[--maxLength] = (uint)sum;
				carry = (uint)(sum >> 32);
				nAddend --;
			}
			while(nAugend > 0)
			{
				sum = augend.values[--nStartAugend];
				sum += carry;
				result.values[--maxLength] = (uint)sum;
				carry = (uint)(sum >> 32);
				nAugend --;
			}
			if(carry > 0)
			{
				result.values[--maxLength] = carry;
			}
			result.nLength = result.nCapacity - maxLength;
			return result;
		}

		/// <summary>
		/// 大整数加无符号整数
		/// </summary>
		/// <param name="augend">被加数(大整数)</param>
		/// <param name="addend">加数(无符号整数)</param>
		/// <returns>返回相加之后的结果</returns>
		public static UBigInteger operator +(UBigInteger augend, uint addend)
		{
			UBigInteger result;
			if(augend.nLength > augend.nCapacity)
			{
				result = new UBigInteger(augend.nCapacity + 1);
			}
			else
			{
				result = new UBigInteger(augend.nCapacity);
			}

			int nEnd = augend.nCapacity;
			int nResultEnd = result.nCapacity;
			int nNumber = augend.nLength;
			while(addend > 0 && nNumber > 0)
			{
				ulong sum = augend.values[--nEnd];
				sum += addend;
				result.values[--nResultEnd] = (uint)sum;
				addend = (uint)(sum >> 32);
				nNumber --;
			}
			if(addend > 0)
			{
				result.values[--nResultEnd] = addend;
			}
			while(nNumber -- > 0)
			{
				result.values[--nResultEnd] = augend.values[--nEnd];
			}
			result.nLength = result.nCapacity - nResultEnd;
			return result;	
		}

		/// <summary>
		/// 重载两国大整数相减运算符
		/// </summary>
		/// <param name="minuend">被减数</param>
		/// <param name="subtrahend">减数</param>
		/// <returns>返回被减数和减数相减的结果,如果被减数小于减数,将返回零</returns>
		public static UBigInteger operator -(UBigInteger minuend, UBigInteger subtrahend)
		{
			UBigInteger result = new UBigInteger(minuend.nLength);
			if((minuend <= subtrahend))
			{
				return result;
			}

			int nEndLeft = minuend.nCapacity;
			int nEndRight = subtrahend.nCapacity;

			int nLeftLength = minuend.nLength;
			int nRightLength = subtrahend.nLength;

			int nEndResult = result.nCapacity;

			ulong temp = 0;
			uint carry = 0;
			while(nRightLength > 0)
			{
				uint nLeft = minuend.values[--nEndLeft];
				uint nRight = subtrahend.values[--nEndRight];
				if(nLeft < nRight || nLeft == nRight && carry > 0)
				{
					temp = 0x100000000u + nLeft;
					result.values[--nEndResult] = (uint)(temp - nRight - carry);
					carry = 1;
				}
				else
				{
					result.values[--nEndResult] = (uint)(nLeft - nRight - carry);
					carry = 0;
				}
				nLeftLength --;
				nRightLength --;
			}
			if(carry > 0)
			{
				while(minuend.values[--nEndLeft] == 0)
				{
					result.values[--nEndResult] = 0xffffffff;
					nLeftLength --;
				}
				result.values[--nEndResult] = minuend.values[nEndLeft] - 1;
				nLeftLength --;
			}
			while(nLeftLength -- >0)
			{
				result.values[--nEndResult] = minuend.values[--nEndLeft];
			}

			while(result.values[nEndResult] == 0)
			{
				nEndResult ++;
			}
			result.nLength = result.nCapacity - nEndResult;//nStart;

			return result;
		}

		/// <summary>
		/// 大整数减去一个无符号整数
		/// </summary>
		/// <param name="minuend">被减数</param>
		/// <param name="subtrahend">减数</param>
		/// <returns>返回大整数减去无符号整数的结果</returns>
		public static UBigInteger operator -(UBigInteger minuend, uint subtrahend)
		{
			UBigInteger result = new UBigInteger(minuend);
			if(minuend.nLength == 0)
				return result;

			int nEnd = result.nCapacity - 1;

			if(result.values[nEnd] > subtrahend)
			{
				result.values[nEnd] -= subtrahend;
				return result;
			}

			if(minuend.nLength == 1)
			{
				result.Assign(0);
				return result;
			}

			ulong temp = 0x100000000u + result.values[nEnd];
			result.values[nEnd] = (uint)(temp - subtrahend);

			while(result.values[--nEnd] ==0)
			{
				result.values[nEnd] = 0xffffffff;
			}
			result.values[nEnd] --;
			if(result.values[nEnd] == 0)
				result.nLength --;

			return result;
		}

		/// <summary>
		/// 重载运算符*进行大整数相乘
		/// </summary>
		/// <param name="faciend">被乘数</param>
		/// <param name="multiplier">乘数</param>
		/// <returns>返回两个大整数相乘的结果</returns>
		public static UBigInteger operator *(UBigInteger faciend, UBigInteger multiplier)
		{
			int maxLength;

			maxLength = faciend.nLength + multiplier.nLength;

			UBigInteger result = new UBigInteger(maxLength);

			int nRight = multiplier.nLength;
			int nEndRight = multiplier.nCapacity;

			while(nRight -- > 0)
			{
				uint nMultiplier = multiplier.values[--nEndRight];

				int nEndLeft = faciend.nCapacity;

				maxLength --;
				int nResultPos = maxLength;

				ulong mul;
				uint carry = 0;
				int nLeft = faciend.nLength;
				while(nLeft -- >0)
				{
					mul = faciend.values[--nEndLeft];
					mul *= nMultiplier;
					mul += carry;
					carry = (uint)(mul >> 32);

					int nEndResult = nResultPos;
					while(carry > 0)
					{
						ulong temp = result.values[--nEndResult];
						temp += carry;
						result.values[nEndResult] = (uint)(temp);
						carry = (uint)(temp >> 32);
					}

					mul &= 0xffffffff;
					mul += result.values[nResultPos];
					result.values[nResultPos] = (uint)mul;
					carry = (uint)(mul >> 32);

					nEndResult = nResultPos;
					while(carry > 0)
					{
						ulong temp = result.values[--nEndResult];
						temp += carry;
						result.values[nEndResult] = (uint)(temp);
						carry = (uint)(temp >> 32);
					}

					nResultPos --;
				}
			}
			result.RefreshLength();

			return result;
		}

		/// <summary>
		/// 大整数和无符号整数相乘
		/// </summary>
		/// <param name="faciend">被乘数</param>
		/// <param name="multiplier">乘数</param>
		/// <returns>返回一个大整数,该大整数是被乘数和乘数相乘的结果</returns>
		public static UBigInteger operator *(UBigInteger faciend, uint multiplier)
		{
			int nLenResult;
			if(faciend.nLength >= faciend.nCapacity)
			{
				nLenResult = faciend.nCapacity+ 1;
			}
			else
			{
				nLenResult = faciend.nCapacity;
			}

			UBigInteger result = new UBigInteger(nLenResult);

			int nLoop = faciend.nLength;
			int nEnd = faciend.nCapacity;
			ulong sum = 0;
			uint carry = 0;
			while(nLoop -- > 0)
			{
				sum = faciend.values[--nEnd];
				sum *= multiplier;
				sum += carry;
				result.values[--nLenResult] = (uint)sum;
				carry = (uint)(sum >> 32);
			}
			if(carry > 0)
			{
				result.values[--nLenResult] = carry;
			}
			result.RefreshLength();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -