一个思路 先将原字符串用ascii编码成byte[] 进行基于字节的加密 (下面的例子我用了0xa0++异或)
然后用base16编码 映射到一个字符串序列上 保证生成的结果全是字母(下面例子我把0-9映射到a-j,a-f映射到u-z)
解密时反过来执行一遍就OK
void Main()
{
CreateMapping();
string enc = Encrypt("abcxyz1234567");
Console.WriteLine(enc);
string dec = Decrypt(enc)
Console.WriteLine(dec);
}
// Define other methods and classes here
static List<KeyValuePair<char,char>> MappingList;
static void CreateMapping(){
MappingList = new List<KeyValuePair<char,char>>();
for(char c='0';c<='9';c++)
MappingList.Add(new KeyValuePair<char,char>(c,(char)(c-'0'+'a')));
for(char c='a';c<='f';c++)
MappingList.Add(new KeyValuePair<char,char>(c,(char)(c-'a'+'u')));
}
static string Encrypt(string str){
return Encoding.ASCII.GetBytes(str)
.Select((b,i)=>(b^((byte)(0xa0+i))).ToString("x2"))
.Aggregate("",(s,c)=>s+c)
.ToCharArray().Select(c=>MappingList.First(kv=>kv.Key==c).Value)
.Aggregate("",(s,c)=>s+c);
}
static string Decrypt(string str){
string base16 = str.ToCharArray()
.Select(c=>MappingList.First(kv=>kv.Value==c).Key)
.Aggregate("",(s,c)=>s+c);
return Encoding.ASCII.GetString((new byte[base16.Length/2])
.Select((b,i)=>(byte)(Convert.ToByte(base16.Substring(i*2,2),16)^((byte)(0xa0+i)))).ToArray());
}
追问那个生成子字符长度可以和原来的字符长度一样长吗
追答逻辑上行不通 你需要建立一个1对1的不重复映射 而字母和数字的域显然比字母域要大 映射是无法成立的
本回答被提问者采纳