public class Kata {
const string alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
const string encr = "KqLrIoJpa6b7Y4Z5CiDjAgBhSyTzQwRxOuPvMsNte f.c8d9GmHnEkFlW2X3U0V1";
public static string Crypt(string text,string input,string output) {
string res = string.Empty;
if(string.IsNullOrEmpty(text)) return(text);
int q = input.IndexOf(text[0]);
if(q<0) throw new System.Exception();
for(int i=1;i<text.Length;i++) {
int p = input.IndexOf(text[i]);
if(p<0) throw new System.Exception();
int s = (p/32)%2-(q/2)%2;
res += output[q+2*s];
q = p-32*s;
}
res += output[q];
return res;
}
public static string Encrypt(string text) {
return(Crypt(text,alph,encr));
}
public static string Decrypt(string encryptedText) {
return(Crypt(encryptedText,encr,alph));
}
}
答案2:
using System;
public class Kata
{
const string chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
public static string Encrypt(string text)
{
if (String.IsNullOrEmpty(text)) return text;
string r="",c;
char [] b;
char [][] t=new char[text.Length][];
int p;
for (int i=0;i<text.Length;i++) if ((p=chars.IndexOf(c=text[i]+""))<0) throw new Exception("Hy Steffen!"); else t[i]=numberToBits(p);
for (int i=0;i<text.Length;i++) {
b=t[i];
if (i<text.Length-1) {char b1=getBit(b,5), b2=getBit(t[i+1],1); setBit(b,5,b2); setBit(t[i+1],1,b1);}//1
b=xorBit(b,2); b=xorBit(b,4); //2
b=swapBits(b,1,4); b=swapBits(b,2,5); b=swapBits(b,3,6); //3
b=swapBits(b,1,2); b=swapBits(b,3,4); b=swapBits(b,5,6); //4
b=reverseBits(b); b=swapBits(b,1,3); //5+6
r+=chars[bitsToNumber(b)];
}
return r;
}
public static string Decrypt(string eText)
{
if (String.IsNullOrEmpty(eText)) return eText;
string r="",c;
char [] b, b1=new char[eText.Length], b5=new char[eText.Length];
char [][] t=new char[eText.Length][];
int p;
for (int i=0;i<eText.Length;i++) if ((p=chars.IndexOf(c=eText[i]+""))<0) throw new Exception("Hy Steffen!"); else t[i]=numberToBits(p);
for (int i=eText.Length-1;i>=0;i--) {
b=t[i];
b=swapBits(b,1,3); b=reverseBits(b); //6+5
b=swapBits(b,1,2); b=swapBits(b,3,4); b=swapBits(b,5,6); //4
b=swapBits(b,1,4); b=swapBits(b,2,5); b=swapBits(b,3,6); //3
b=xorBit(b,2); b=xorBit(b,4); //2
b1[i]=getBit(b,1); b5[i]=getBit(b,5); //later on for rule 1
t[i]=b;
}
for (int i=eText.Length-2;i>=0;i--) {t[i]=setBit(t[i],5,b1[i+1]); t[i+1]=setBit(t[i+1],1,b5[i]);}
for (int i=0;i<eText.Length;i++) r+=chars[bitsToNumber(t[i])];
return r;
}
public static char[] numberToBits(int num) {char[] r=new char[6]; for (int i=5; i>=0; i--) r[5-i]=((1<<i)&num)>0?'1':'0'; return r;}
public static int bitsToNumber(char[] bits) {int r=0; for (int i=0; i<=5; i++) r+=bits[i]=='1'?1<<(5-i):0; return r;}
public static char[] swapBits(char[] num, int bit1, int bit2) {char t=num[bit1-1]; num[bit1-1]=num[bit2-1]; num[bit2-1]=t; return num;}
public static char[] xorBit(char[] num, int bit) {num[bit-1]=num[bit-1]=='1'?'0':'1'; return num;}
public static char[] reverseBits(char[] bits) {char[] r=new char[6]; for (int i=5; i>=0; i--) r[5-i]=bits[i]; return r;}
public static char getBit(char[] bits, int bit) {return bits[bit-1];}
public static char[] setBit(char[] bits, int bit, char value) {bits[bit-1]=value; return bits;}
}
答案3:
using System;//for using Func<>
using System.Linq;//for using x.Contains()
public class Kata
{
public static string Encrypt(string text)
{
if (text == null || text == "")//return the string if it is null or empty
return text;
char[] key = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', '.'};
string encryptedText = "";//the above array is used to convert each char into a number. The string encryptedText will be returned with the encoded message
Func<char, string> CharToBin = new Func<char, string> (x => Convert.ToString(Array.IndexOf(key, x), 2));//returns the binary representation of the position in key of a given char
for (int i = 0; i < text.Length; i++)//for every char in the input string
{
if (!key.Contains(text[i]))//if the char is not in the array of acceptable characters, throw an exception
throw new System.Exception();
char previousBit = i > 0 ? ("00000" + CharToBin(text[i - 1]))[("00000" + CharToBin(text[i - 1])).Length - 2] : ' ', nextBit = i < text.Length - 1 ? ("00000" + CharToBin(text[i + 1]))[("00000" + CharToBin(text[i + 1])).Length - 6] : ' ';//previousBit is the bit at position 4 (5th) of the last character, or 0 if there is no previous char. nextBit is the bit at position 0 (1st) of the next char. Leading 0's are appended to ensure the string is at least 6 bits long.
string encryptedBin = EncryptNextChar("00000" + CharToBin(text[i]), previousBit, nextBit);//returns the encrypted result of a given 6 bit binary string
Func<string, char> BinToChar = new Func<string, char> (x => key[Convert.ToInt32(x, 2)]);//returns the char that is represented by the binary string given
encryptedText += BinToChar(encryptedBin);//converts the encrypted binary back to a char, and appends it to the end of encryptedText to be returned
}
return encryptedText;//returns the encrypted string
}
public static string EncryptNextChar(string bits, char previousBit, char nextBit)
{
Func<char, char> Inverse = new Func<char, char> (x => x == '0' ? '1' : '0');//returns the inverse of a given bit
char a = bits[bits.Length - 6], b = bits[bits.Length - 5], c = bits[bits.Length - 4], d = bits[bits.Length - 3], e = bits[bits.Length - 2], f = bits[bits.Length - 1];//a b c d e f are the bits at position 0 1 2 3 4 5 respectively of the string bits
if (previousBit == ' ' && nextBit == ' ')//if no char before or after
return f.ToString() + c.ToString() + Inverse(b).ToString() + a.ToString() + Inverse(d).ToString() + e.ToString();//this is the how the bits end up after the encryption shuffles them
else if (previousBit == ' ')//if no char before
return f.ToString() + c.ToString() + Inverse(b).ToString() + a.ToString() + Inverse(d).ToString() + nextBit.ToString();//this is the how the bits end up after the encryption shuffles them
else if (nextBit == ' ')//if no char after
return f.ToString() + c.ToString() + Inverse(b).ToString() + previousBit.ToString() + Inverse(d).ToString() + e.ToString();//this is the how the bits end up after the encryption shuffles them
else//if a char in the middle of a string
return f.ToString() + c.ToString() + Inverse(b).ToString() + previousBit.ToString() + Inverse(d).ToString() + nextBit.ToString();//this is the how the bits end up after the encryption shuffles them
}
public static string Decrypt(string encryptedText)
{
if (encryptedText == null || encryptedText == "")//return the string if it is null or empty
return encryptedText;
char[] key = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', '.'};
string text = "";//the above array is used to convert each char into a number. The string text will be returned with the decoded message
Func<char, string> CharToBin = new Func<char, string> (x => Convert.ToString(Array.IndexOf(key, x), 2));//returns the binary representation of the position in key of a given char
for (int i = 0; i < encryptedText.Length; i++)//for every char in the input string
{
if (!key.Contains(encryptedText[i]))//if the char is not in the array of acceptable characters, throw an exception
throw new System.Exception();
char previousBit = i > 0 ? ("00000" + CharToBin(encryptedText[i - 1]))[("00000" + CharToBin(encryptedText[i - 1])).Length - 1] : ' ', nextBit = i < encryptedText.Length - 1 ? ("00000" + CharToBin(encryptedText[i + 1]))[("00000" + CharToBin(encryptedText[i + 1])).Length - 3] : ' ';//previousBit is the bit at position 5 (6th) of the last character, or 0 if there is no previous char. nextBit is the bit at position 3 (4th) of the next char. Leading 0's are appended to ensure the string is at least 6 bits long. These positions are different to encryption due to how the encryption process shuffles the bits.
string decryptedBin = DecryptNextChar("00000" + CharToBin(encryptedText[i]), previousBit, nextBit);//returns the decrypted result of a given 6 bit binary string
Func<string, char> BinToChar = new Func<string, char> (x => key[Convert.ToInt32(x, 2)]);//returns the char that is represented by the binary string given
text += BinToChar(decryptedBin); //converts the decrypted binary back to a char, and appends it to the end of text to be returned
}
return text;//returns the decrypted string
}
public static string DecryptNextChar(string bits, char previousBit, char nextBit)
{
Func<char, char> Inverse = new Func<char, char> (x => x == '0' ? '1' : '0');//returns the inverse of a given bit
char a = bits[bits.Length - 6], b = bits[bits.Length - 5], c = bits[bits.Length - 4], d = bits[bits.Length - 3], e = bits[bits.Length - 2], f = bits[bits.Length - 1];//a b c d e f are the bits at position 0 1 2 3 4 5 respectively of the string bits
if (previousBit == ' ' && nextBit == ' ')//if no char before or after
return d.ToString() + Inverse(c).ToString() + b.ToString() + Inverse(e).ToString() + f.ToString() + a.ToString();//this is how to rearrange the bits to unshuffle them
else if (previousBit == ' ')//if no char before
return d.ToString() + Inverse(c).ToString() + b.ToString() + Inverse(e).ToString() + nextBit.ToString() + a.ToString();//this is how to rearrange the bits to unshuffle them
else if (nextBit == ' ')//if no char after
return previousBit.ToString() + Inverse(c).ToString() + b.ToString() + Inverse(e).ToString() + f.ToString() + a.ToString();//this is how to rearrange the bits to unshuffle them
else//if a char in the middle of a string
return previousBit.ToString() + Inverse(c).ToString() + b.ToString() + Inverse(e).ToString() + nextBit.ToString() + a.ToString();//this is how to rearrange the bits to unshuffle them
}
}
答案4:
using System;
using System.Linq;
using System.Text;
public class Kata
{
private static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
private static byte GetIndexByte(char c) => Convert.ToByte(Alphabet.IndexOf(c));
private static char GetIndexChar(byte b) => Alphabet[Convert.ToInt32(b)];
private static bool GetBitValue(byte b, int i) => (b & (1 << 6 - i)) != 0;
private static byte SetBitValue(byte b, int i, bool value) => Convert.ToByte(value ? (b | (1 << 6 - i)) : (b & ~(1 << 6 - i)));
public static string Encrypt(string text)
{
// Throw out invalid input
if (string.IsNullOrEmpty(text)) return text;
if (text.Any(c => !Alphabet.Contains(c))) throw new Exception("Illegal character detected");
// Cycle through each character in the string and perform bit-wise operations to encrypt them
var builder = new StringBuilder();
var enc = text.ToCharArray();
for (int i = 0; i < enc.Length; i++)
{
var currentByte = GetIndexByte(enc[i]);
// Swap Byte1/Bit5 with Byte2/Bit1 (if there is a Byte2)
if (i < enc.Length - 1)
{
var nextByte = GetIndexByte(enc[i + 1]);
var value = GetBitValue(nextByte, 1);
nextByte = SetBitValue(nextByte, 1, GetBitValue(currentByte, 5));
currentByte = SetBitValue(currentByte, 5, value);
enc[i + 1] = GetIndexChar(nextByte);
}
// Read all bits, operate on them, and set them based on the encryption rules
var b1 = GetBitValue(currentByte, 1);
var b2 = GetBitValue(currentByte, 2);
var b3 = GetBitValue(currentByte, 3);
var b4 = GetBitValue(currentByte, 4);
var b5 = GetBitValue(currentByte, 5);
var b6 = GetBitValue(currentByte, 6);
currentByte = SetBitValue(currentByte, 1, b6);
currentByte = SetBitValue(currentByte, 2, b3);
currentByte = SetBitValue(currentByte, 3, !b2);
currentByte = SetBitValue(currentByte, 4, b1);
currentByte = SetBitValue(currentByte, 5, !b4);
currentByte = SetBitValue(currentByte, 6, b5);
builder.Append(GetIndexChar(currentByte));
}
return builder.ToString();
}
public static string Decrypt(string encryptedText)
{
// Throw out invalid input
if (string.IsNullOrEmpty(encryptedText)) return encryptedText;
if (encryptedText.Any(c => !Alphabet.Contains(c))) throw new Exception("Illegal character detected");
// Cycle through each character in the string (in reverse order) and perform bit-wise operations to decrypt them
var builder = new StringBuilder();
var dec = encryptedText.ToCharArray();
byte nextByte = byte.MaxValue;
for (int i = dec.Length - 1; i >= 0; i--)
{
var currentByte = GetIndexByte(dec[i]);
// Read all bits, operate on them, and set them based on the decryption rules
var b1 = GetBitValue(currentByte, 1);
var b2 = GetBitValue(currentByte, 2);
var b3 = GetBitValue(currentByte, 3);
var b4 = GetBitValue(currentByte, 4);
var b5 = GetBitValue(currentByte, 5);
var b6 = GetBitValue(currentByte, 6);
currentByte = SetBitValue(currentByte, 1, b4);
currentByte = SetBitValue(currentByte, 2, !b3);
currentByte = SetBitValue(currentByte, 3, b2);
currentByte = SetBitValue(currentByte, 4, !b5);
currentByte = SetBitValue(currentByte, 5, b6);
currentByte = SetBitValue(currentByte, 6, b1);
// Swap Byte1/Bit5 with Byte2/Bit1 (if there is a Byte2)
if (i < dec.Length - 1)
{
var value = GetBitValue(nextByte, 1);
nextByte = SetBitValue(nextByte, 1, GetBitValue(currentByte, 5));
currentByte = SetBitValue(currentByte, 5, value);
dec[i + 1] = GetIndexChar(nextByte);
}
if (nextByte < byte.MaxValue) builder.Append(GetIndexChar(nextByte));
nextByte = currentByte;
}
builder.Append(GetIndexChar(nextByte));
return new string(builder.ToString().Reverse().ToArray());
}
}
答案5:
using System;
public class Kata
{
public static string Encrypt(string text)
{
if (text == null) return null;
if (text == "") return "";
string region = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
string first = "";
if (region.IndexOf(text[0])==-1) throw new Exception();
string second = Convert.ToString(region.IndexOf(text[0]), 2);
while (second.Length < 6)
second = "0" + second;
for (int i = 0; i < text.Length; i++)
{
first = second;
if (i + 1 < text.Length)
{
if (region.IndexOf(text[i+1])==-1) throw new Exception();
second = Convert.ToString(region.IndexOf(text[i + 1]), 2);
while (second.Length < 6)
second = "0" + second;
string temp = first.Substring(4, 1);
first = first.Remove(4, 1).Insert(4, second[0].ToString());
second = temp + second.Substring(1);
}
// 2
if (first[1] == '1') first = first.Remove(1, 1).Insert(1, "0");
else first = first.Remove(1, 1).Insert(1, "1");
if (first[3] == '1') first = first.Remove(3, 1).Insert(3, "0");
else first = first.Remove(3, 1).Insert(3, "1");
// 3
first = first.Substring(3, 3) + first.Substring(0, 3);
// 4
for (int j = 0; j < 6; j += 2)
{
first = first.Remove(j + 1, 1).Insert(j, first[j + 1].ToString());
}
//5
string s = "";
for (int j = first.Length - 1; j >= 0; j--)
{
s += first[j];
}
first = s;
//6
first = first[2] + (first.Substring(1)).Remove(1, 1).Insert(1, first[0].ToString());
int index = Convert.ToInt32(first, 2);
text = text.Remove(i, 1).Insert(i, region[index].ToString());
}
return text;
}
public static string Decrypt(string encryptedText)
{
if (encryptedText == null) return null;
if (encryptedText == "") return "";
string region = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
if (region.IndexOf(encryptedText[encryptedText.Length-1])==-1) throw new Exception();
string first = "";
string second = Convert.ToString(region.IndexOf(encryptedText[encryptedText.Length-1]), 2);
while (second.Length < 6)
second = "0" + second;
second = Decoding(second);
for (int i = encryptedText.Length-1; i >= 0; i--)
{
first = second;
if (i - 1 >= 0)
{
if (region.IndexOf(encryptedText[i-1])==-1) throw new Exception();
second = Convert.ToString(region.IndexOf(encryptedText[i - 1]), 2);
while (second.Length < 6)
second = "0" + second;
second = Decoding(second);
string temp = second.Substring(4, 1);
second = second.Remove(4, 1).Insert(4, first[0].ToString());
first = temp + first.Substring(1);
}
int index = Convert.ToInt32(first, 2);
encryptedText = encryptedText.Remove(i, 1).Insert(i, region[index].ToString());
}
return encryptedText;
}
public static string Decoding(string first)
{
//6
first = first[2] + (first.Substring(1)).Remove(1, 1).Insert(1, first[0].ToString());
//5
string s = "";
for (int j = first.Length - 1; j >= 0; j--)
{
s += first[j];
}
first = s;
// 4
for (int j = 0; j < 6; j += 2)
{
first = first.Remove(j + 1, 1).Insert(j, first[j + 1].ToString());
}
// 3
first = first.Substring(3, 3) + first.Substring(0, 3);
// 2
if (first[1] == '1') first = first.Remove(1, 1).Insert(1, "0");
else first = first.Remove(1, 1).Insert(1, "1");
if (first[3] == '1') first = first.Remove(3, 1).Insert(3, "0");
else first = first.Remove(3, 1).Insert(3, "1");
return first;
}
}