能力值:
( LV3,RANK:20 )
|
-
-
2 楼
虽然我最擅长的领域不是算法,但偶尔客串一下还是可以的。(上次做“有道难题”的在线答题,只得了一个及格分......不爽,所以希望我的回答能满足搂主的需求。)
我希望大家可以把DONET发扬光大,让看雪开一个DONET板块是最终目的!
希望大家能讨论更多的DONET问题。
private string GetEncyptString(string inputString, int intKey)
{
ushort num = (ushort)intKey;
char[] chArray = new char[4 * inputString.Length];
for (int i = 0; i < inputString.Length; i++)
{
ushort num3 = (ushort)(inputString[i] + num);
string str = new string(new char[] { this.GetNewChar((byte)(num3 & 15)), this.GetNewChar((byte)((num3 >> 4) & 15)), this.GetNewChar((byte)((num3 >> 8) & 15)), this.GetNewChar((byte)((num3 >> 12) & 15)) });
chArray[4 * i] = str[0];
chArray[(4 * i) + 1] = str[1];
chArray[(4 * i) + 2] = str[2];
chArray[(4 * i) + 3] = str[3];
num = (ushort)(num + 0x6fd);
}
return new string(chArray);
}
private char GetNewChar(byte value)
{
return (char)(0x61 + value);
}
|
能力值:
( LV9,RANK:140 )
|
-
-
3 楼
一看楼上的算法就知道不用验证了。牛人,正解!想不到会这么快,佩服!
在阅读看雪帖子的过程中,对楼上印象深刻,还望以后多多指教。
下面是手动反流程后的IL代码。只要象个精干的妇人收拾屋子般,把它们规整的有序而决不多余就成了。
.method public hidebysig static string
x9919(string x12346_1,
int32 x12347_2) cil managed
{
// 代码大小 158 (0x9e)
.maxstack 5
.locals init (unsigned int16 V_0,
char[] V_1,
int32 V_2,
unsigned int16 V_3)
ldarg.1 //参数 1 入栈,int32 x12347_2
conv.u2 //将位于计算堆栈顶部的值转换为 unsigned int16,然后将其扩展为 int32
stloc.0 //出栈到V_0 int16型
ldarg.0 //参数 0 入栈,那个入参string x12346_1
callvirt instance int32 [mscorlib]System.String::get_Length() //调用求字符串儿长度函数
ldc.i4.4 //将整数值 4 作为 int32 推送到计算堆栈上
div //除,上面的串儿长度除以4?
newarr [mscorlib]System.Char //Create a zero-base, on-dimensional array
stloc.1 //出栈到V_1,那个char[]数组
ldc.i4.0 //将整数值 0 作为 int32 推送到计算堆栈上
stloc.2 //出栈到V_2,那个int32 V_2的临时变量
IL_WHILE: ldloc.2 //V_2入栈,int32 V_2,第一次到此处时为0
ldarg.0 //参数0入栈,那个string
callvirt instance int32 [mscorlib]System.String::get_Length() //又调用求串儿长度
ldc.i4.4 ////将整数值 4 作为 int32 推送到计算堆栈上 //这段儿和标签IL_0061及其后的作用一样,好象,往下跑着看
div //除,上面的串儿长度除以4?
blt.s IL_IF //小于跳转
ldloc.1
br.s IL_END
IL_IF: ldarg.0 ////参数0入栈,那个string
ldc.i4.4 //将整数值 4 作为 int32 推送到计算堆栈上
ldloc.2 //V_2入栈,int32 V_2
mul //乘 4*V_2入栈
callvirt instance char [mscorlib]System.String::get_Chars(int32) //据一个int32值取它对应的字符
ldc.i4.s 97 //将 num 作为 int32 推送到堆栈上(短格式)。
sub //减97
ldarg.0 //参数0入栈,那个string
ldc.i4.4 //将整数值 4 作为 int32 推送到计算堆栈上
ldloc.2 ///V_2入栈,int32 V_2
mul //乘 4*V_2入栈
ldc.i4.1 //将整数值 1 作为 int32 推送到计算堆栈上
add //加 4*V_2+1
callvirt instance char [mscorlib]System.String::get_Chars(int32) //据一个int32值取它对应的字符
ldc.i4.s 97 //将 num 作为 int32 推送到堆栈上(短格式)。
sub //减
ldc.i4.4 //将整数值 4 作为 int32 推送到计算堆栈上
shl //左移,移上面指出的4位,后面补0
add //加
ldarg.0 ////参数0入栈,那个string
ldc.i4.4 //将整数值 4 作为 int32 推送到计算堆栈上
ldloc.2 //V_2入栈,int32 V_2
mul //从栈取两值乘,结果入栈
ldc.i4.2 //将整数值2 作为 int32 推送到计算堆栈上
add //从栈取两值加,结果入栈
callvirt instance char [mscorlib]System.String::get_Chars(int32) //据一个int32值取它对应的字符
ldc.i4.s 97 //将 num 作为 int32 推送到堆栈上(短格式)。
sub //减
ldc.i4.8 //将整数值8作为 int32 推送到计算堆栈上
shl //左移8位
add
ldarg.0
ldc.i4.4
ldloc.2
mul
ldc.i4.3
add
callvirt instance char [mscorlib]System.String::get_Chars(int32)
ldc.i4.s 97
sub
ldc.i4.s 12
shl
add
conv.u2
stloc.3
ldloc.3
ldloc.0
sub
conv.u2
stloc.3
ldloc.1
ldloc.2
ldloc.3
stelem.i2
ldloc.0
ldc.i4 0x6fd
add
conv.u2
stloc.0
ldloc.2
ldc.i4.1
add
stloc.2
// ldloc.2 //V_2入栈,int32 V_2,第一次到此处时为0
br.s IL_WHILE ////跳到标签处
IL_END: newobj instance void [mscorlib]System.String::.ctor(char[])
ret
} // end of method Form1::x9919 现在可以看到可读性强的代码了,比如C#:
private static string x9919(string x12346_1, int x12347_2)
{
ushort num = (ushort) x12347_2;
char[] chArray = new char[x12346_1.Length / 4];
for (int i = 0; i < (x12346_1.Length / 4); i++)
{
ushort num3 = (ushort) ((((x12346_1[4 * i] - 'a') + ((x12346_1[(4 * i) + 1] - 0x61) << 4)) + ((x12346_1[(4 * i) + 2] - 0x61) << 8)) + ((x12346_1[(4 * i) + 3] - 0x61) << 12));
num3 = (ushort) (num3 - num);
chArray[i] = (char) num3;
num = (ushort) (num + 0x6fd);
}
return new string(chArray);
}
那么对比一下楼上的反函数。。。感觉那个---美!
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
tease 强悍
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
厉害学习一下
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
tease 高人.
|
|
|