我编写了一个程序,使用随机键对文本进行编码。使用密钥时,即使我仅使用一个字母进行编码,解码器的结果也是完全错误的
这是用于加密/解密的函数,以及用于生成具有确定长度的随机密钥的函数:
string XOR_String(string text, string key)
{
var result = new StringBuilder();
for (int c = 0; c < text.Length; c++)
result.Append((char)((uint)text[c] ^ (uint)key[c % key.Length]));
return result.ToString();
}
private static string RandomString(int Size)
{
Random random = new Random();
string input = "abcdefghijklmnopqrstuvwxyz0123456789";
var chars = Enumerable.Range(0, Size)
.Select(x => input[random.Next(0, input.Length)]);
return new string(chars.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
解密:
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.FileName = "data.txt";
openFileDialog1.Title = "Open file";
openFileDialog1.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
file = openFileDialog1;
fs = new System.IO.FileStream(file.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
reader = new System.IO.StreamReader(fs);
file_contents = reader.ReadToEnd();
if (textBox1.Text != "")
{
data = XOR_String(file_contents, textBox1.Text);
reader.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
加密:
private void button2_Click(object sender, EventArgs e)
{
System.IO.FileInfo file_info = new System.IO.FileInfo(file.FileName);
long file_info_length = file_info.Length;
int file_length = checked((int)file_info_length);
String key = RandomString(file_length);
textBox1.Text = key;
data = XOR_String(file_contents, key);
System.IO.File.WriteAllText(file.FileName, data);
reader.Close();
}
Run Code Online (Sandbox Code Playgroud)
您确实意识到C#/。Net / CLR世界中的字符串是UTF-16编码的Unicode,对吗?
http://en.wikipedia.org/wiki/UTF-16
基本多语言平面中代码点处的那些字符(范围U + 0000–U + D7FF和U + E000–U + FFFF)仅表示为单个16位字符。
您对字符进行随机XOR运算将导致随机内容无法往返:它将是无效的UTF-16或替代对。
那是你的问题。
如果要编码这样的内容,请尝试以下操作:
byte[]从要编码的字符串中创建一个。byte[]密文转换为Base64编码的字符串Convert.ToBase64String()。要对其进行解码,请逆向处理:
byte[]using Convert.FromBase64String()。byte[]使用最初使用的相同编码将结果纯文本转换回C#/。Net字符串。编辑注意:
只是为了好玩...
一个测试用例:
MyNotVerySecureCrypto crypto = new MyNotVerySecureCrypto("cat" ) ;
string plainText = "The quick brown fox jumped over the lazy dog." ;
string cipherText = crypto.Encrypt(plainText) ;
string plainText1 = crypto.Decrypt(cipherText) ;
Debug.Assert(plainText.Equals(plainText1,StringComparison.Ordinal));
Run Code Online (Sandbox Code Playgroud)要测试此代码:
public class MyNotVerySecureCrypto
{
private byte[] Key { get ; set ; }
private Encoding Encoding { get ; set ; }
public MyNotVerySecureCrypto( string key , Encoding encoding )
{
this.Encoding = encoding ;
this.Key = Encoding.GetBytes(key).Where( b => b != 0 ).ToArray() ;
return ;
}
public MyNotVerySecureCrypto( string key ) : this ( key , Encoding.UTF8 )
{
return ;
}
public string Encrypt( string plainText )
{
int i = 0 ;
byte[] octets = Encoding
.GetBytes(plainText)
.Select( b => (byte) (b^Key[(++i)%Key.Length]) )
.ToArray()
;
string cipherText = Convert.ToBase64String(octets) ;
return cipherText ;
}
public string Decrypt( string cipherText )
{
int i = 0 ;
byte[] octets = Convert
.FromBase64String(cipherText)
.Select( b => (byte) (b^Key[(++i)%Key.Length]) )
.ToArray()
;
string plainText = Encoding.GetString( octets ) ;
return plainText ;
}
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1525 次 |
| 最近记录: |