对给定的明文进行加密,比双轨加密更加复杂,破解难度更大。
明文排成矩阵,密钥写在矩阵的上边,按密钥字母在字母表中排序把矩阵按列写出即为密文。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SSLHomework1.Service
{
///
/// 钥控加密
///
class KeyControl : IKeyControl
{
///
/// 加密
///
///
///
public string Encrypt(string content,string key) {
if (content.Length>0 && key.Length>0) {
List<string> ciphertext = new List<string>(); //存放密文
var resultKey = getSequence(KeyHanding(key)); //获取处理后的key信息
int groupNum = content.Length / resultKey.Length; //分片数
int groupLength = groupNum * resultKey.Length; //分片总长度
int leftLenth = content.Length - groupLength; //分片后剩余的部分长
//对于分组内的数据处理
for (int i = 0; i < resultKey.Length; i++) {
ciphertext.Add(string.Empty); //实例化密文对象
bool tag = true;
int length = 0; //间隔位置
while (tag) {
ciphertext[i] += content[i + length].ToString();
length += resultKey.Length; //跳到下一片
if (!(length < groupLength)) {
tag = false; //如果超出分片总长则跳出
}
}
}
//对于分组外的数据处理
if (leftLenth>0) {
for (int i = 0; i < leftLenth; i++) {
ciphertext[i] += content[i + groupLength];//将分片后剩余的部分加入到密文
}
} else {
Console.WriteLine("没有分组后的剩余部分");
}
// Console.WriteLine(string.Join("\n", ciphertext).ToUpper());
//将分组后的密文按照密钥序列排列,并将字母全部转换成大写
return string.Join("\n",changeTheOrder(resultKey,ciphertext)).ToUpper();
} else {
Console.WriteLine("没有明文或者没有密钥");
return string.Empty;
}
}
///
/// 解密
///
///
///
public string Deciphering(string content,string key) {
if (content.Length>0 && key.Length>0) {
List<string> decryption = new List<string>();
string result = string.Empty;
var resultKey = getUnSequence(getSequence(KeyHanding(key)));//获取解密的密钥
var contentArray = changeTheOrder(resultKey,content.Split("\n").ToArray().ToList());//获取原来序列的密文
// Console.WriteLine(string.Join("\n",contentArray));
var groupNum = GetShortest(contentArray);//获取加密时选择的分片数
//先按照最短的字符串划分原来的分片内容
for (int i = 0; i < groupNum; i++) {
string temp = string.Empty;
for (int j = 0; j < resultKey.Length; j++) {
temp += contentArray[j][i].ToString();//对每片都取同一位置的字符
}
decryption.Add(temp.ToLower());
}
// Console.WriteLine(string.Join("", decryption));
result = string.Join("", decryption);
//将剩余的1一个字符拼接回原来的分片
for (int i = 0; i < resultKey.Length; i++) {
if (contentArray[i].Length>groupNum) {
result +=
contentArray[i].ToLower()[groupNum];
}
}
return result;
} else {
return string.Empty;
}
}
///
/// 对密钥处理,返回处理后的密钥以及密钥序列
///
///
///
private string KeyHanding(string key) {
string result = string.Empty;
int length = key.Length;
if (length > 0) {
string newKey = string.Empty;
int ilength = length - 1;
//获取除去重复字符后的密钥
int i;
for (i=0; i < ilength; i++) {
bool tag = false;//是否有重复标记,false为无,有为true
for (int j = i+1; j < length; j++) {
if (key[i].Equals(key[j])) {
tag = true;
break;
}
}
//不重复时则把它的值取出来,重复的取最后一个不重复的值
if (!tag) {
newKey += key[i].ToString();
}
}
newKey += key[i].ToString();
// Console.WriteLine(newKey);//获得新的密钥
result = newKey;
} else {
Console.WriteLine("没有密钥");
}
return result;
}
///
/// 获取序列数组
///
///
///
private string getSequence(string newKey) {
//获取出去重复字符后的密钥序列数组
List<int> sequence = new List<int>();
int length = newKey.Length - 1;
for (int k = 0; k < newKey.Length; k++)
{
sequence.Add(0);
}
// Console.WriteLine(string.Join("", sequence));
int ilength = newKey.Length - 1;
for (int i = 0; i < ilength; i++)
{
for (int j = i + 1; j < newKey.Length; j++)
{
if (newKey[i] < newKey[j]) {
sequence[j]++;
} else if (newKey[i] > newKey[j]) {
sequence[i]++;
}
}
}
// Console.WriteLine(string.Join("",sequence));
return string.Join("", sequence);
}
///
/// 获取反序列数组
///
///
///
private string getUnSequence(string newKey)
{
//根据密钥获取反序列
List<int> sequence = new List<int>();
for (int k = 0; k < newKey.Length; k++)
{
sequence.Add(0);
}
var listKey = newKey.ToList();
for (int i = 0; i < newKey.Length; i++) {
// Console.WriteLine(listKey.FindIndex(ss=> ss.Equals((char)(i + 48))));
sequence[i] = listKey.FindIndex(x=> x.Equals((char)(i + 48)));
}
// Console.WriteLine(string.Join("",sequence));
return string.Join("", sequence);
}
///
/// 交换序列顺序
///
///
///
///
private List<string> changeTheOrder(string resultKey,
List<string> ciphertext)
{
List<string> result = new List<string>();
int keyNum = 0;
while (keyNum < resultKey.Length)
{
for (int i = 0; i < resultKey.Length; i++)
{
if (keyNum.Equals(resultKey[i] - 48))
{
result.Add(ciphertext[i]);
break;
}
}
keyNum++;
}
return result;
}
///
/// 获取最短组
///
///
///
private int GetShortest(List<string> content)
{
if (content.Count > 0)
{
int shortest = content[0].Length;
foreach (var p in content)
{
if (p.Length < shortest)
{
shortest = p.Length;
}
}
return shortest;
}
else
{
return 0;
}
}
}
}
码云keyControl分支
(https://gitee.com/plasma/Information-security-basics-study-notes.git)