#c# #.net #visual-studio #encryption
Вопрос:
Как молодой разработчик программного обеспечения, я всегда хотел создать шифрование простого текста, и это мое начало, надеюсь, чего-то большего.
Но это простое шифрование превращает строчные и прописные буквы в определенное статическое число с . после, чтобы представить конец буквы, но при расшифровке это то же самое, но перевернуто, но по какой-то причине это не работает, как показано ниже.
Ввод обычного текста: abcd Вывод зашифрованного текста: 01.10.1.11. Вывод расшифрованного текста: abc1c
Ниже приведен блок кода шифрования и дешифрования.
public static string CCENC(string plainText)
{
// Encrypt Lowercase and Captial Letters
if (plainText.Contains("a")) { string num = plainText.Replace("a", "01."); plainText = num; };
if (plainText.Contains("A")) { string num = plainText.Replace("A", "11010."); plainText = num; };
if (plainText.Contains("b")) { string num = plainText.Replace("b", "10."); plainText = num; };
if (plainText.Contains("B")) { string num = plainText.Replace("B", "110."); plainText = num; };
if (plainText.Contains("c")) { string num = plainText.Replace("c", "1."); plainText = num; };
if (plainText.Contains("C")) { string num = plainText.Replace("C", "0."); plainText = num; };
if (plainText.Contains("d")) { string num = plainText.Replace("d", "11."); plainText = num; };
if (plainText.Contains("D")) { string num = plainText.Replace("D", "00."); plainText = num; };
if (plainText.Contains("e")) { string num = plainText.Replace("e", "010."); plainText = num; };
if (plainText.Contains("E")) { string num = plainText.Replace("E", "001."); plainText = num; };
if (plainText.Contains("f")) { string num = plainText.Replace("f", "1100."); plainText = num; };
if (plainText.Contains("F")) { string num = plainText.Replace("F", "0011."); plainText = num; };
if (plainText.Contains("g")) { string num = plainText.Replace("g", "00001."); plainText = num; };
if (plainText.Contains("G")) { string num = plainText.Replace("G", "01010."); plainText = num; };
if (plainText.Contains("h")) { string num = plainText.Replace("h", "110011."); plainText = num; };
if (plainText.Contains("H")) { string num = plainText.Replace("H", "110110."); plainText = num; };
if (plainText.Contains("i")) { string num = plainText.Replace("i", "1111."); plainText = num; };
if (plainText.Contains("I")) { string num = plainText.Replace("I", "000011."); plainText = num; };
if (plainText.Contains("j")) { string num = plainText.Replace("j", "03."); plainText = num; };
if (plainText.Contains("J")) { string num = plainText.Replace("J", "30."); plainText = num; };
if (plainText.Contains("k")) { string num = plainText.Replace("k", "003."); plainText = num; };
if (plainText.Contains("K")) { string num = plainText.Replace("K", "030."); plainText = num; };
if (plainText.Contains("l")) { string num = plainText.Replace("l", "330."); plainText = num; };
if (plainText.Contains("L")) { string num = plainText.Replace("L", "003."); plainText = num; };
if (plainText.Contains("m")) { string num = plainText.Replace("m", "333."); plainText = num; };
if (plainText.Contains("M")) { string num = plainText.Replace("M", "0030."); plainText = num; };
if (plainText.Contains("n")) { string num = plainText.Replace("n", "30300."); plainText = num; };
if (plainText.Contains("N")) { string num = plainText.Replace("N", "30330."); plainText = num; };
if (plainText.Contains("o")) { string num = plainText.Replace("o", "33033."); plainText = num; };
if (plainText.Contains("O")) { string num = plainText.Replace("O", "303033."); plainText = num; };
if (plainText.Contains("p")) { string num = plainText.Replace("p", "30033."); plainText = num; };
if (plainText.Contains("P")) { string num = plainText.Replace("P", "33003."); plainText = num; };
if (plainText.Contains("q")) { string num = plainText.Replace("q", "13."); plainText = num; };
if (plainText.Contains("Q")) { string num = plainText.Replace("Q", "31."); plainText = num; };
if (plainText.Contains("r")) { string num = plainText.Replace("r", "1131."); plainText = num; };
if (plainText.Contains("R")) { string num = plainText.Replace("R", "33113."); plainText = num; };
if (plainText.Contains("s")) { string num = plainText.Replace("s", "31313."); plainText = num; };
if (plainText.Contains("S")) { string num = plainText.Replace("S", "7."); plainText = num; };
if (plainText.Contains("t")) { string num = plainText.Replace("t", "7331."); plainText = num; };
if (plainText.Contains("T")) { string num = plainText.Replace("T", "1337."); plainText = num; };
if (plainText.Contains("u")) { string num = plainText.Replace("u", "37."); plainText = num; };
if (plainText.Contains("U")) { string num = plainText.Replace("U", "17."); plainText = num; };
if (plainText.Contains("v")) { string num = plainText.Replace("v", "70."); plainText = num; };
if (plainText.Contains("V")) { string num = plainText.Replace("V", "07."); plainText = num; };
if (plainText.Contains("w")) { string num = plainText.Replace("w", "701."); plainText = num; };
if (plainText.Contains("W")) { string num = plainText.Replace("W", "107."); plainText = num; };
if (plainText.Contains("x")) { string num = plainText.Replace("x", "037."); plainText = num; };
if (plainText.Contains("X")) { string num = plainText.Replace("X", "3307."); plainText = num; };
if (plainText.Contains("y")) { string num = plainText.Replace("y", "11773."); plainText = num; };
if (plainText.Contains("Y")) { string num = plainText.Replace("Y", "1073."); plainText = num; };
if (plainText.Contains("z")) { string num = plainText.Replace("z", "7771."); plainText = num; };
if (plainText.Contains("Z")) { string num = plainText.Replace("Z", "33107."); plainText = num; };
// Add Branding
string fplainText = "CC-ENC|" plainText;
return fplainText;
}
public static string CCDEC(string encryptedText)
{
// Remove Branding
if (encryptedText.Contains("CC-ENC|")) { string num = encryptedText.Replace("CC-ENC|", ""); encryptedText = num; };
// Decrypt Lowercase and Captial Letters
if (encryptedText.Contains("01.")) { string num = encryptedText.Replace("01.", "a"); encryptedText = num; };
if (encryptedText.Contains("11010.")) { string num = encryptedText.Replace("11010.", "A"); encryptedText = num; };
if (encryptedText.Contains("10.")) { string num = encryptedText.Replace("10.", "b"); encryptedText = num; };
if (encryptedText.Contains("110.")) { string num = encryptedText.Replace("110.", "B"); encryptedText = num; };
if (encryptedText.Contains("1.")) { string num = encryptedText.Replace("1.", "c"); encryptedText = num; };
if (encryptedText.Contains("0.")) { string num = encryptedText.Replace("0.", "C"); encryptedText = num; };
if (encryptedText.Contains("11.")) { string num = encryptedText.Replace("11.", "d"); encryptedText = num; };
if (encryptedText.Contains("00.")) { string num = encryptedText.Replace("00.", "D"); encryptedText = num; };
if (encryptedText.Contains("010.")) { string num = encryptedText.Replace("010.", "e"); encryptedText = num; };
if (encryptedText.Contains("001.")) { string num = encryptedText.Replace("001.", "E"); encryptedText = num; };
if (encryptedText.Contains("1100.")) { string num = encryptedText.Replace("1100.", "f"); encryptedText = num; };
if (encryptedText.Contains("0011.")) { string num = encryptedText.Replace("0011.", "F"); encryptedText = num; };
if (encryptedText.Contains("00001.")) { string num = encryptedText.Replace("00001.", "g"); encryptedText = num; };
if (encryptedText.Contains("01010.")) { string num = encryptedText.Replace("01010.", "G"); encryptedText = num; };
if (encryptedText.Contains("110011.")) { string num = encryptedText.Replace("110011.", "h"); encryptedText = num; };
if (encryptedText.Contains("110110.")) { string num = encryptedText.Replace("110110.", "H"); encryptedText = num; };
if (encryptedText.Contains("1111.")) { string num = encryptedText.Replace("1111.", "i"); encryptedText = num; };
if (encryptedText.Contains("000011.")) { string num = encryptedText.Replace("000011.", "I"); encryptedText = num; };
if (encryptedText.Contains("03.")) { string num = encryptedText.Replace("03.", "j"); encryptedText = num; };
if (encryptedText.Contains("30.")) { string num = encryptedText.Replace("30.", "J"); encryptedText = num; };
if (encryptedText.Contains("003.")) { string num = encryptedText.Replace("003.", "k"); encryptedText = num; };
if (encryptedText.Contains("030.")) { string num = encryptedText.Replace("030.", "K"); encryptedText = num; };
if (encryptedText.Contains("330.")) { string num = encryptedText.Replace("330.", "l"); encryptedText = num; };
if (encryptedText.Contains("003.")) { string num = encryptedText.Replace("003.", "L"); encryptedText = num; };
if (encryptedText.Contains("333.")) { string num = encryptedText.Replace("333.", "m"); encryptedText = num; };
if (encryptedText.Contains("0030.")) { string num = encryptedText.Replace("0030.", "M"); encryptedText = num; };
if (encryptedText.Contains("30300.")) { string num = encryptedText.Replace("30300.", "n"); encryptedText = num; };
if (encryptedText.Contains("30330.")) { string num = encryptedText.Replace("30330.", "N"); encryptedText = num; };
if (encryptedText.Contains("33033.")) { string num = encryptedText.Replace("33033.", "o"); encryptedText = num; };
if (encryptedText.Contains("303033.")) { string num = encryptedText.Replace("303033.", "O"); encryptedText = num; };
if (encryptedText.Contains("30033.")) { string num = encryptedText.Replace("30033.", "p"); encryptedText = num; };
if (encryptedText.Contains("33003.")) { string num = encryptedText.Replace("33003.", "P"); encryptedText = num; };
if (encryptedText.Contains("13.")) { string num = encryptedText.Replace("13.", "q"); encryptedText = num; };
if (encryptedText.Contains("31.")) { string num = encryptedText.Replace("31.", "Q"); encryptedText = num; };
if (encryptedText.Contains("1131.")) { string num = encryptedText.Replace("1131.", "r"); encryptedText = num; };
if (encryptedText.Contains("33113.")) { string num = encryptedText.Replace("33113.", "R"); encryptedText = num; };
if (encryptedText.Contains("31313.")) { string num = encryptedText.Replace("31313.", "s"); encryptedText = num; };
if (encryptedText.Contains("7.")) { string num = encryptedText.Replace("7.", "S"); encryptedText = num; };
if (encryptedText.Contains("7331.")) { string num = encryptedText.Replace("7331.", "t"); encryptedText = num; };
if (encryptedText.Contains("1337.")) { string num = encryptedText.Replace("1337.", "T"); encryptedText = num; };
if (encryptedText.Contains("37.")) { string num = encryptedText.Replace("37.", "u"); encryptedText = num; };
if (encryptedText.Contains("17.")) { string num = encryptedText.Replace("17.", "U"); encryptedText = num; };
if (encryptedText.Contains("70.")) { string num = encryptedText.Replace("70.", "v"); encryptedText = num; };
if (encryptedText.Contains("07.")) { string num = encryptedText.Replace("07.", "V"); encryptedText = num; };
if (encryptedText.Contains("701.")) { string num = encryptedText.Replace("701.", "w"); encryptedText = num; };
if (encryptedText.Contains("107.")) { string num = encryptedText.Replace("107.", "W"); encryptedText = num; };
if (encryptedText.Contains("037.")) { string num = encryptedText.Replace("037.", "x"); encryptedText = num; };
if (encryptedText.Contains("3307.")) { string num = encryptedText.Replace("3307.", "X"); encryptedText = num; };
if (encryptedText.Contains("11773.")) { string num = encryptedText.Replace("11773.", "y"); encryptedText = num; };
if (encryptedText.Contains("1073.")) { string num = encryptedText.Replace("1073.", "Y"); encryptedText = num; };
if (encryptedText.Contains("7771.")) { string num = encryptedText.Replace("7771.", "z"); encryptedText = num; };
if (encryptedText.Contains("33107.")) { string num = encryptedText.Replace("33107.", "Z"); encryptedText = num; };
return encryptedText;
}
Комментарии:
1. Самое важное, что вам нужно изучить, — это то, как использовать отладчик .
2. Ваш код будет легче читать (и писать), если вы замените каждую строку, например
if (plainText.Contains("a")) { string num = plainText.Replace("a", "01."); plainText = num; };
, эквивалентным операторомplainText = plainText.Replace("a", "01.");
В качестве бонуса, этот подход также более эффективен. Вы также можете связывать вызовы по цепочкеReplace
, как вplainText = plainText.Replace("a", "01.").Replace("b", "10.");
и так далее. Но создание коллекции ваших замен, как предлагается в другом месте, действительно является гораздо лучшим подходом. Это не только проще реализовать, но и легче улучшить.3. @Echox, есть какие-нибудь новости? Пожалуйста, проверьте, подходят ли вам следующие ответы.
Ответ №1:
Ваша расшифровка неоднозначна …
Рассмотрим ваш пример 01.10.1.11.
Если вы посмотрите на свой метод расшифровки, у вас есть куча if
s, которые выполняются сверху вниз.
if (encryptedText.Contains("01.")) // replace with a
... => encryptedText = "a10.1.11."
if (encryptedText.Contains("10.")) // replace with b
... => encryptedText = "ab1.11."
if (encryptedText.Contains("1.")) //replace with c
Так что же происходит в этой последней строке? В вашей строке ab1.11.
он заменяет каждый экземпляр 1.
на c, что приводит к abc1c
ie, результату, который вы видите.
Поэтому, чтобы ваша схема шифрования работала, вы должны убедиться, что более короткие замены не являются частью более длинных или, по крайней мере, что более длинные проверяются ранее … Это только один пример двусмысленности. Другие, например,
q - R - S
r - T
V - W - X - Z
и многие другие тоже.
Кроме того, если вы действительно хотите построить схему шифрования с таблицей подстановок (см. Ниже, почему это не такая хорошая идея), вы можете значительно упростить свою жизнь, если поместите таблицу подстановок в какую-то коллекцию и просто повторите эту коллекцию вместо написания такого каскада if
условий
using System;
public class Program
{
static (string, string)[] substitutions = new(string, string)[] {
("a", "10."),
("b", "11."),
("c", "1."),
...
};
static string encrypt(string plain) {
var encrypted = plain;
foreach (var s in substitutions) {
encrypted = encrypted.Replace(s.Item1, s.Item2);
}
return encrypted;
}
static string decrypt(string encrypted) {
var plain = encrypted;
foreach (var s in substitutions) {
plain = plain.Replace(s.Item2, s.Item1);
}
return plain;
}
public static void Main()
{
var plain = "abc";
var encrypted = encrypt(plain);
var plain2 =decrypt(encrypted);
Console.WriteLine(plain);
Console.WriteLine(encrypted);
Console.WriteLine(plain2);
}
}
Что касается безопасности: Простые шифры с подстановкой являются очень слабыми шифрами, потому что большинство языков имеют хорошо известное распределение символов, поэтому, если символ всегда заменяется одним и тем же номером, довольно легко догадаться, какое число кодирует какой символ … Я настоятельно не рекомендую использовать такой шифр-даже если он реализован правильно-в любой среде, где безопасность имеет какое-то значение. Пожалуйста, используйте хорошо зарекомендовавшие себя и хорошо разработанные стандарты шифрования …
Комментарии:
1. Просто чтобы повторить один из пунктов @derpirscher. Пожалуйста, не используйте шифры подстановки ни для чего, кроме академических целей. Самостоятельно реализуемые алгоритмы криптографии, особенно со слабой криптографической сложностью, не рекомендуются для любого использования, кроме хобби и образования.
Ответ №2:
Основываясь на своем тесте, я воспроизвел вашу проблему. Я не рекомендую вам использовать методы string.replace и string.contains для получения результата, потому что код все равно заменит данные 1.
в 11.
.
Вот пример кода, на который вы можете сослаться, который может решить эту проблему.
static void Main(string[] args)
{
string str1 = "CC-ENC|11010.01.10.1.11.";
string str2 = "Aabcd";
string m = CCENC(str2);
Console.WriteLine(m);
string n = CCDEC(str1);
Console.WriteLine(n);
Console.ReadKey();
}
public static string CCDEC(string encryptedText)
{
// Remove Branding
string num = "";
if (encryptedText.Contains("CC-ENC|")) { num = encryptedText.Replace("CC-ENC|", ""); encryptedText = num; };
string[] arr = num.Split('.');
string result = "";
foreach (var item in arr)
{
switch (item)
{
case "01":
result = result "a";
break;
case "10":
result = result "b";
break;
case "1":
result = result "c";
break;
case "11":
result = result "d";
break;
case "11010":
result = result "A";
break;
.
.
.
default:
Console.WriteLine("other case");
break;
}
}
return resu<
}
public static string CCENC(string plainText)
{
string[] arr = plainText.Select(i=>i.ToString()).ToArray();
string result = "";
foreach (var item in arr)
{
switch (item)
{
case "a":
result = result "01.";
break;
case "b":
result = result "10.";
break;
case "c":
result = result "1.";
break;
case "d":
result = result "11.";
break;
case "A":
result = result "11010.";
break;
.
.
.
default:
break;
}
}
// Add Branding
string fplainText = "CC-ENC|" resu<
return fplainText;
}
Кроме того, если у вас есть два разных условия, я предлагаю вам попробовать использовать switch...case
предложение.
Результат: