疑难:加密函数-中文和英文的写法

永远的铁道兵 2016-10-27 09:21:25
原加密程序是用delphi 写的, delphi 的 char 和C# 的char 不一样,后者是unicode 字符。
因此问题就来了,没有中文加密的时候,如下函数是没有问题的,一旦账号是中文,则加密字符串就对不上了。

private string Encode7(string EnStr, char[] s)
{
int i, n1, n2;
char FStr1, FStr2, FStr3, Fchar1;
string Result = EnStr;
for (i = 0; i < s.Length; i++)
{
if (i <= 3)
{
FStr1 = s[i];
FStr2 = Result[i];
FStr3 = Result[28 + i];
n1 = ((Convert.ToInt32(s[i]) - 32) % 8);
n2 = ((Convert.ToInt32(s[i]) - 32) / 16);
Fchar1 = Convert.ToChar(n2 * 16 + 32);
n2 = Convert.ToInt32(FStr2) ^ Convert.ToInt32(FStr1);
n2 = (n2 & 0x0F) + 0x20;
FStr2 = Convert.ToChar(n2);
FStr3 = Convert.ToChar(Convert.ToInt32(Fchar1) + ((Convert.ToInt32(FStr3) + Convert.ToInt32(Fchar1)) % 16));
Result = Result.Substring(0, i) + FStr2 + Result.Substring(i + 1, 31 - i);
Result = Result.Substring(0, 28 + i) + FStr3 + Result.Substring(29 + i, 3 - i);
}
else
{
FStr1 = s[i];
FStr2 = Result[i];
FStr3 = Result[i - 4];
n1 = ((Convert.ToInt32(s[i]) - 32) % 16);
n2 = ((Convert.ToInt32(s[i]) - 32) / 16);
Fchar1 = Convert.ToChar(n2 * 16 + 32);
n2 = Convert.ToInt32(FStr2) ^ Convert.ToInt32(FStr1);
n2 = (n2 & 0x0F) + 0x20;
FStr2 = Convert.ToChar(n2);
FStr3 = Convert.ToChar(Convert.ToInt32(Fchar1) + ((Convert.ToInt32(FStr3) + Convert.ToInt32(Fchar1)) % 16));
Result = Result.Substring(0, i) + FStr2 + Result.Substring(i + 1, 31 - i);
Result = Result.Substring(0, i - 4) + FStr3 + Result.Substring(i - 3, 35 - i);
}


}
return Result;
}

private string EnUser(char[] s)
{
string fnil = "'(&.&!'%&$\"'&)\" \",&)$(%#$-$#$$\" ";
string FF1 = " !\"#$%&'()*+,-./";

int n, i, d;
string Result;
i = s.Length;
Result = fnil.Substring((i - 1) * 2, 30 - (i - 1) * 2);

for (n = i-1; n >= 0; n--)
{ i = (Convert.ToInt32(s[n]) - 32) % 16;

d = ((Convert.ToInt32(s[n]) - 32) / 16) + 1;

Result = Result + Convert.ToChar(32 + d + 1) + FF1[i];

}
return Result;



方法调用: Encode7(EnUser(username), password);
思索几天无果, 我先把 文本转换成ANSI,得到双倍数组,但是数组元素每2个才可以转换一个汉字,加密还是失败。
byte[] bwrite = Encoding.Default.GetBytes(username);
这个考验基本功了,非计算机科班出身,对中文编码和英文编码没有研究,实在没办法,特此发帖请大神指点。
...全文
179 7 打赏 收藏 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
Encoding.Default慎用,这在不同的语言环境下,值是不同的,按你中文的话,那你应该改为Encoding.GetEncoding("gb2312")
永远的铁道兵 2016-10-28
  • 打赏
  • 举报
回复
搞定了,谢谢各位前辈。 关键的一句 Encode7(EnUserByte(Encoding.Default.GetBytes(textBoxName.Text)), password); 先转换ANSI编码,再用byte数组。

  /// <summary>
        /// 适合中文和英文
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private string EnUserByte(byte[] s)
        {
            string fnil = "'(&.&!'%&$\"'&)\" \",&)$(%#$-$#$$\" ";
            string FF1 = " !\"#$%&'()*+,-./";

            int n, i, d;
            string Result;
            i = s.Length; 
            Result = fnil.Substring((i - 1) * 2, 30 - (i - 1) * 2);

            for (n = i - 1; n >= 0; n--)
            {
                i = (Convert.ToInt32(s[n]) - 32) % 16;  

                d = ((Convert.ToInt32(s[n]) - 32) / 16) + 1;      

                Result = Result + Convert.ToChar(32 + d + 1) + FF1[i];

            }
            return Result;
        }
  • 打赏
  • 举报
回复
Encoding.UTF8.GetBytes 大家统一获取bytes的编码格式
WM_JAWIN 2016-10-28
  • 打赏
  • 举报
回复
Delphi 的char 应该是对应C#里的byte
永远的铁道兵 2016-10-28
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
[quote=引用 楼主 qq_34545753 的回复:] 思索几天无果, 我先把 文本转换成ANSI,得到双倍数组,但是数组元素每2个才可以转换一个汉字,加密还是失败。 byte[] bwrite = Encoding.Default.GetBytes(username);
程序流程本身就不应该按照 char 来设计,而应该按照 byte 来设计流程! 然后,了解你的原来的 Delphi 程序的字符串编码形式,在 c# 程序中将字符串按照同样地编码方式,将字符串转换为 byte[ ]。这样,在加密解密之前,你从 Delphi 和 c# 程序中得到的 byte[ ] 数据是一模一样的,每一个字节都一样! 你可以看到,逻辑上根本就跟“加密、解密”无关!在加密之前你用不同程序所得到的 byte[ ] 就应该一样。[/quote] 谢谢了,看过你回复的很多帖子。 HTML + AJAX + ASHX 就是在你的提点下学习入门的,还有最经典的一句,少用ASPX重型武器。 我再研究看看。
  • 打赏
  • 举报
回复
引用 楼主 qq_34545753 的回复:
思索几天无果, 我先把 文本转换成ANSI,得到双倍数组,但是数组元素每2个才可以转换一个汉字,加密还是失败。 byte[] bwrite = Encoding.Default.GetBytes(username);
程序流程本身就不应该按照 char 来设计,而应该按照 byte 来设计流程! 然后,了解你的原来的 Delphi 程序的字符串编码形式,在 c# 程序中将字符串按照同样地编码方式,将字符串转换为 byte[ ]。这样,在加密解密之前,你从 Delphi 和 c# 程序中得到的 byte[ ] 数据是一模一样的,每一个字节都一样! 你可以看到,逻辑上根本就跟“加密、解密”无关!在加密之前你用不同程序所得到的 byte[ ] 就应该一样。
  • 打赏
  • 举报
回复
引用 楼主 qq_34545753 的回复:
原加密程序是用delphi 写的, delphi 的 char 和C# 的char 不一样,后者是unicode 字符。 因此问题就来了,
这是逻辑概念错误问题。 加密解密都是针对 byte[ ] 数据而言的,产生的结果也是 byte[ ] 数据。不管用什么编程语言,不管字符串是不是使用 unicode 来存储,你都应该将你的字符串按照你的目标的编码方式转换为 byte[ ]。 怎能纠结 char 数据?

111,128

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧