![]()
using System.Text;
namespace Cipher.Algorithm
{
static class Caesar
{
static public string Encrypt(string input, int key)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < input.Length; ++i)
{
if ('a' <= input[i] && input[i] <= 'z')
{
sb.Append((char)((input[i] - 'a' + key + 26) % 26 + 'a'));
}
else if ('A' <= input[i] && input[i] <= 'Z')
{
sb.Append((char)((input[i] - 'A' + key + 26) % 26 + 'A'));
}
else
{
sb.Append(input[i]);
}
}
return sb.ToString();
}
static public string Decrypt(string input, int key)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; ++i)
{
if ('a' <= input[i] && input[i] <= 'z')
{
sb.Append((char)((input[i] - 'a' - key + 26) % 26 + 'a'));
}
else if ('A' <= input[i] && input[i] <= 'Z')
{
sb.Append((char)((input[i] - 'A' - key + 26) % 26 + 'A'));
}
else
{
sb.Append(input[i]);
}
}
return sb.ToString();
}
}
}
using System;
using System.Text;
namespace Cipher.Algorithm
{
public class Hill
{
// 矩阵阶数
private int _level;
// 加密矩阵
private long[][] _matrix;
// 解密矩阵
private long[][] _inverseMatrix = null;
private int _times = 0;
// 用于填充的无效字符
const char INVALID_CHAR = 'A';
/// <summary>
/// 带阶数的构造函数
/// </summary>
/// <param name="level">矩阵阶数</param>
public Hill(int level)
{
_level = level;
while(_inverseMatrix == null)
{
_matrix = getRandomMatrix();
_inverseMatrix = getInverseMatrix(_matrix);
++_times;
}
;
}
public Hill(int level, long[][] matrix)
{
_level = level;
_matrix = matrix;
_inverseMatrix = getInverseMatrix(_matrix);
if (null == _inverseMatrix) _inverseMatrix = getNewMatrix();
}
#region Properties
public int Level
{
get
{
return _level;
}
}
/// <summary>当前矩阵
/// </summary>
public long[][] Matrix
{
get
{
return _matrix;
}
}
public long[][] InverseMatrix
{
get
{
return _inverseMatrix;
}
}
public int Times
{
get
{
return _times;
}
}
#endregion
/// <summary>
/// 得到一个新的整数矩阵
/// </summary>
/// <returns>矩阵</returns>
public long[][] getNewMatrix()
{
long[][] res = new long[_level][];
for (int i = 0; i < _level; ++i) res[i] = new long[_level];
for (int i = 0; i < _level; ++i)
for (int j = 0; j < _level; ++j) res[i][j] = 0;
return res;
}
/// <summary>
/// 得到一个n阶整数矩阵
/// </summary>
/// <param name="level">阶数</param>
/// <returns>矩阵</returns>
public static long[][] getNewMatrix(int level)
{
long[][] res = new long[level][];
for (int i = 0; i < level; ++i) res[i] = new long[level];
for (int i = 0; i < level; ++i)
for (int j = 0; j < level; ++j) res[i][j] = 0;
return res;
}
/// <summary>
/// 求关于MOD26的逆矩阵
/// </summary>
/// <param name="o">原矩阵</param>
/// <returns>逆矩阵</returns>
private long[][] getInverseMatrix(long[][] o)
{
long[][] res = getNewMatrix();
long[][] original = getNewMatrix();
for (int i = 0; i < _level; ++i)
{
for (int j = 0; j < _level; ++j)
{
if (i == j) res[i][j] = 1;
else res[i][j] = 0;
original[i][j] = o[i][j];
}
}
for (int k = 0; k <_level; ++k)
{
bool isGCD = false;
for (int i = k; i < _level; ++i)
{
if (GCD(original[i][k], 26) == 1)
{
isGCD = true;
if (i != k)
{
long[] temp1 = original[i], temp2 = res[i];
original[i] = original[k]; res[i] = res[k];
original[k] = temp1; res[k] = temp2;
}
break;
}
}
// 若矩阵一列中没有与26互素的元素,则认为该矩阵不可逆
if (!isGCD) return null;
long ie = getInverseElement(original[k][k], 26);
Console.WriteLine(original[k][k] + "的逆元是:" + ie);
if (-1 == ie) return null;
for (int j = 0; j < _level; ++j)
{
original[k][j] = (original[k][j] * ie) % 26;
res[k][j] = (res[k][j] * ie) % 26;
}
for (int i = k + 1; i < _level; ++i)
{
long l = original[i][k] / original[k][k];
for (int j = 0; j < _level; ++j)
{
// 对增广矩阵的运算
res[i][j] = getMOD((res[i][j] - l * res[k][j]), 26);
// 对原矩阵的运算
original[i][j] = getMOD((original[i][j] - l * original[k][j]), 26);
}
}
}
for (int k = _level - 1; k > 0; --k)
{
if (original[k][k] == 0) return null;
for (int i = k - 1; i >= 0; --i)
{
long l = original[i][k] / original[k][k];
// 对增广矩阵的运算
for (int j = 0; j < _level; ++j)
{
if (res[k][j] == 0) continue;
res[i][j] = getMOD((res[i][j] - l * res[k][j]), 26);
}
// 对原矩阵的运算
original[i][k] = getMOD((original[i][k] - l * original[k][k]), 26);
}
}
return res;
}
private long getMOD(long x, long m)
{
while (x < m)
{
x += m;
}
return x % m;
}
/// <summary>
/// 求a关于m的乘法逆元
/// </summary>
/// <param name="a"></param>
/// <param name="m"></param>
/// <returns>逆元</returns>
public static long getInverseElement(long a, long m)
{
long x = 0, y = 0;
long gcd = E_GCD(a, m, ref x, ref y);
if (1 % gcd != 0) return -1;
x *= 1 / gcd;
m = Math.Abs(m);
long res = x % m;
if (res <= 0) res += m;
return res;
}
/// <summary>
/// 拓展欧几里德算法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>GCD(a, b)</returns>
public static long E_GCD(long a, long b, ref long x, ref long y)
{
if (0 == b)
{
x = 1;
y = 0;
return a;
}
long res = E_GCD(b, a % b, ref x, ref y);
long temp = x;
x = y;
y = temp - a / b * y;
return res;
}
/// <summary>
/// 求最大公约数
/// </summary>
/// <param name="x">第一个参数</param>
/// <param name="y">第二个参数</param>
/// <returns>最大公约数</returns>
static public long GCD(long x, long y)
{
if (y == 0) return x;
return GCD(y, x % y);
}
static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
private long[][] getRandomMatrix()
{
long[][] res = getNewMatrix();
for (int i = 0; i < _level; ++i)
{
for (int j = 0; j < _level; ++j)
{
int t;
Random rd = new Random(GetRandomSeed());
t = rd.Next(0, 26);
res[i][j] = t;
}
}
return res;
}
private string getOneGroup(string input, long[][] matrix)
{
StringBuilder sb = new StringBuilder();
int[] p = new int[_level];
for (int i = 0; i < _level; ++i)
{
if (i < input.Length)
p[i] = input[i] - 'A';
else p[i] = INVALID_CHAR;
}
for (int i = 0; i < _level; ++i)
{
long o = 0;
for (int j = 0; j < _level; ++j)
{
o += matrix[i][j] * p[j] ;
}
Console.Write(o.ToString() + " ");
sb.Append((char)(o % 26 + 'A'));
}
Console.WriteLine();
return sb.ToString();
}
/// <summary>
/// 加密
/// </summary>
/// <param name="input">请确保输入的字符串只有字母</param>
/// <returns></returns>
public string Encrypt(string input)
{
StringBuilder sb = new StringBuilder();
input = input.ToUpper();
for (int i = 0; i < input.Length; i += _level)
{
int end = _level < (input.Length - i) ? _level : (input.Length - i);
sb.Append(getOneGroup(input.Substring(i, end), _matrix));
}
return sb.ToString();
}
public string Decrypt(string input)
{
StringBuilder sb = new StringBuilder();
input = input.ToUpper();
for (int i = 0; i < input.Length; i += _level)
{
int end = _level < (input.Length - i) ? _level : (input.Length - i);
sb.Append(getOneGroup(input.Substring(i, end), _inverseMatrix));
}
return sb.ToString();
}
}
}
using System.Text;
using System.Windows;
namespace Cipher.Algorithm
{
public static class Playfair
{
private static char[,] _key = new char[5, 5]; // 经过处理的5×5矩阵
private static Point[] _location = new Point[26]; // 26个字母在key中的位置
private static string _group; // 分组后的字符串
private static char _ch = 'Q'; // 无效字母,如Q, K, X
public static string Encrypt(string input)
{
StringBuilder sb = new StringBuilder();
string str = group(input);
for(int i = 0; i < str.Length; i += 2)
{
int r1 = (int)(_location[str[i] - 'A'].X);
int r2 = (int)(_location[str[i + 1] - 'A'].X);
int c1 = (int)(_location[str[i] - 'A'].Y);
int c2 = (int)(_location[str[i + 1] - 'A'].Y);
// 字母同行
if (r1 == r2)
{
sb.Append(_key[r1, (c1 + 1) % 5]).Append(_key[r1, (c2 + 1) % 5]);
}
// 字母同列
else if (c1 == c2)
{
sb.Append(_key[(r1 + 1) % 5, c1]).Append(_key[(r2 + 1) % 5, c1]);
}
else
{
if (r1 > r2 && c1 > c2)
{
sb.Append(_key[r1, c2]).Append(_key[r2, c1]);
}
else if (r1 < r2 && c1 > c2)
{
sb.Append(_key[r2, c1]).Append(_key[r1, c2]);
}
else if (r1 > r2 && c1 < c2)
{
sb.Append(_key[r1, c2]).Append(_key[r2, c1]);
}
else
{
sb.Append(_key[r2, c1]).Append(_key[r1, c2]);
}
}
}
return sb.ToString();
}
public static string Decrypt(string input)
{
StringBuilder sb = new StringBuilder();
string str = (string)input.ToUpper();
if (str.Length % 2 == 1 || str.Length == 0 || str.IndexOf(' ') != -1) return "";
for (int i = 0; i < str.Length; i += 2)
{
int r1 = (int)(_location[str[i] - 'A'].X);
int r2 = (int)(_location[str[i + 1] - 'A'].X);
int c1 = (int)(_location[str[i] - 'A'].Y);
int c2 = (int)(_location[str[i + 1] - 'A'].Y);
// 字母同行
if (r1 == r2)
{
sb.Append(_key[r1, (c1 - 1 + 5) % 5]).Append(_key[r1, (c2 - 1 + 5) % 5]);
}
// 字母同列
else if (c1 == c2)
{
sb.Append(_key[(r1 - 1 + 5) % 5, c1]).Append(_key[(r2 - 1 + 5) % 5, c1]);
}
else
{
if (r1 > r2 && c1 > c2)
{
sb.Append(_key[r1, c2]).Append(_key[r2, c1]);
}
else if (r1 < r2 && c1 > c2)
{
sb.Append(_key[r2, c1]).Append(_key[r1, c2]);
}
else if (r1 > r2 && c1 < c2)
{
sb.Append(_key[r1, c2]).Append(_key[r2, c1]);
}
else
{
sb.Append(_key[r2, c1]).Append(_key[r1, c2]);
}
}
}
for(int i = 2; i < sb.Length; ++i)
{
if(sb[i].Equals(sb[i - 2]) && sb[i - 1].Equals(_ch))
{
sb.Remove(i - 1, 1);
}
}
if (sb[sb.Length - 1].Equals(_ch)) sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
public static char[, ] Key(string word)
{
string temp = word.ToUpper();
StringBuilder sb = new StringBuilder();
bool[] flag = new bool[26];
for(int i = 0; i < temp.Length; ++i)
{
// 该字母未出现过
if (flag[temp[i] - 'A'] == false)
{
sb.Append(temp[i]);
}
flag[temp[i] - 'A'] = true;
}
for(int i = 0; i < 26; ++i)
{
if (i == 'J' - 'A')
{
continue;
}
if (flag[i] == false)
{
sb.Append((char)(i + 'A'));
}
}
for (int i = 0; i < 5; ++i)
{
for(int j = 0; j < 5; ++j)
{
_key[i, j] = sb[i * 5 + j];
Point insert = new Point(i, j);
_location[_key[i, j] - 'A'] = insert;
}
}
return _key;
}
private static string group(string input)
{
StringBuilder sb = new StringBuilder();
string temp = input.ToUpper();
for(int i = 0; i < temp.Length; )
{
if (0 != i && sb.Length > 0 && temp[i] == sb[sb.Length - 1])
{
sb.Append(_ch);
}
else if ('A' <= temp[i] && temp[i] <= 'Z')
{
sb.Append(temp[i]);
++i;
}
else
{
++i;
}
}
if (sb.Length % 2 == 1)
{
sb.Append(_ch);
}
_group = sb.ToString();
return sb.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Cipher.Algorithm
{
class Rd
{
public static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
namespace Cipher.Algorithm
{
class RSA
{
// 已保存的素数集
protected int[] primes = { 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389 };
protected BigInteger rsa_e;
protected BigInteger rsa_d;
protected BigInteger rsa_n;
protected BigInteger rsa_p;
protected BigInteger rsa_q;
#region Properties
public string P
{
get
{
return rsa_p.ToString();
}
}
public string Q
{
get
{
return rsa_q.ToString();
}
}
public string E
{
get
{
return rsa_e.ToString();
}
}
public string D
{
get
{
return rsa_d.ToString();
}
}
public string N
{
get
{
return rsa_n.ToString();
}
}
#endregion
public RSA()
{
BigInteger p, q;
p = getRandomPrime();
q = getRandomPrime();
while (p == q)
{
// 确保p与q不相等
q = getRandomPrime();
}
BigInteger n = p * q;
BigInteger fi_n = (p - 1) * (q - 1);
BigInteger e = getRandomPrime();
while (GCD(fi_n, e) != 1)
{
e = getRandomPrime();
}
BigInteger d = getInverseElement(e, fi_n);
rsa_e = e;
rsa_d = d;
rsa_n = n;
rsa_p = p;
rsa_q = q;
}
public RSA(BigInteger p, BigInteger q, BigInteger e)
{
rsa_p = p;
rsa_q = q;
rsa_e = e;
BigInteger n = p * q;
BigInteger fi_n = (p - 1) * (q - 1);
if (GCD(fi_n, e) != 1) return;
BigInteger d = getInverseElement(e, fi_n);
rsa_d = d;
rsa_n = n;
}
public BigInteger[] Encrypt(string input)
{
List<BigInteger> res = new List<BigInteger>();
char[] c = input.ToArray();
for (int i = 0; i < c.Length; ++i)
{
res.Add(EncryptSingle(c[i], rsa_e));
}
return res.ToArray();
}
public char[] Decrypt(BigInteger[] input)
{
List<char> res = new List<char>();
for (int i = 0; i < input.Length; ++i)
{
int ch = Int32.Parse(EncryptSingle(input[i], rsa_d).ToString());
res.Add((char)ch);
}
return res.ToArray();
}
/// <summary>
/// 对单个字符进行幂运算加密
/// </summary>
/// <param name="input"></param>
/// <param name="m"></param>
/// <returns></returns>
protected BigInteger EncryptSingle(BigInteger input, BigInteger m)
{
BigInteger res = 1;
for (int i = 0; i < m; ++i)
{
res = (res * input) % rsa_n;
}
return res;
}
protected BigInteger getRandomPrime()
{
Random rd = new Random(Rd.GetRandomSeed());
BigInteger res = new BigInteger(primes[rd.Next(0, primes.Length)]);
return res;
}
protected BigInteger GCD(BigInteger a, BigInteger b)
{
if (b == BigInteger.Zero) return a;
return GCD(b, a % b);
}
/// <summary>
/// 求a关于m的乘法逆元
/// </summary>
/// <param name="a">原数</param>
/// <param name="m">被MOD的数</param>
/// <returns>逆元</returns>
protected BigInteger getInverseElement(BigInteger a, BigInteger m)
{
BigInteger x = 0, y = 0;
BigInteger gcd = E_GCD(a, m, ref x, ref y);
if (1 % gcd != 0) return -1;
x *= 1 / gcd;
m = BigInteger.Abs(m);
BigInteger res = x % m;
if (res <= 0) res += m;
return res;
}
/// <summary>
/// 拓展欧几里德算法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>GCD(a, b)</returns>
protected BigInteger E_GCD(BigInteger a, BigInteger b, ref BigInteger x, ref BigInteger y)
{
if (0 == b)
{
x = 1;
y = 0;
return a;
}
BigInteger res = E_GCD(b, a % b, ref x, ref y);
BigInteger temp = x;
x = y;
y = temp - a / b * y;
return res;
}
}
}