我在处理 LINQ-to-Entities 中的 8 位“ASCII”字符时遇到了一个有趣的问题,希望有人能给我一个提示。
我继承了一个 SQL Server 2000 数据库,该数据库具有一些伪加密列,它们只是将字符串与0xFF
. 不知道为什么,我知道这很糟糕,但这就是我们现在所处的位置。
这些列是 SQL 数据类型char(7)
和char(14)
. 当您使用 XOR 时,0xFF
您在每种情况下都会设置第 8 位,因此您最终会得到非 ASCII(无论如何按照微软的定义)字符。这里似乎显示了 UTF-8,但解码却搞砸了。
我能够读取和解码这些字符串,如下所示:
- 使用 LINQ 作为
String
. - 得到一个
byte[]
使用System.Text.Encoding.GetEncoding(1252).GetBytes()
- 通过对每个字节进行异或解码
0xFF
- 返回解码后的字符串
System.Text.Encoding.GetEncoding(1252).GetString()
这完美地工作。
我遇到的问题是我似乎无法使用 LINQ 将编码字符串放回 SQL Server。
我基本上遵循相反的过程并且正在做:
- 使用 获取字节
ASCIIEncoding.GetBytes()
。(此处不需要 CodePage 1252,因为这是一个直字符串。) - 用 编码字节
0xFF
。 - 用 . 返回编码后的字符串
GetEncoding(1252).GetString()
。
如果我看一下我的字符串,这正是我所期望的。但是,如果我在我的实体中填充它并执行SaveChanges()
SQL Server 中的结果值总是"?????"
有一定的长度。
我确定我在这里遗漏了一些东西,但我已经尝试了所有我能想到的但无法得到它。SqlCommand
现在我只是回到使用 a并使用编码字符串作为 UPDATE的老式方法SqlParameters
。那里没问题,每次都有效。
提前感谢您的任何帮助。
更新:
我尝试了 JamieSee 的建议,但我什至没有用他的方法得到很好的解码。我有:
static void Main(string[] args)
{
Encoding characterEncoding = Encoding.GetEncoding(28591);
HCBPWEBEntities ent = new HCBPWEBEntities();
var encUser =
(from users in ent.tblEmployer
where users.ipkEmpId == 357
select users.sKey).First();
Console.Out.WriteLine("Original XOR Encoded PW: {0}", encUser.ToString().Trim());
byte[] originalBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
select (byte)(character)).ToArray();
Console.Write("Original Bytes:\t");
foreach (byte b in originalBytes)
{
Console.Write("{0:x} ", b);
}
Console.WriteLine(String.Empty);
byte[] decodedBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
select (byte)(character ^ 0xFF)).ToArray();
Console.Write("Decoded Bytes:\t");
foreach (byte b in decodedBytes)
{
Console.Write("{0:x} ", b);
}
Console.WriteLine(String.Empty);
string decoded = characterEncoding.GetString(decodedBytes);
Console.WriteLine("Decoded PW: {0}", decoded);
ent.Dispose();
}
但这样做的结果是:
原始 XOR 编码密码:z?o> 原始字节:7a 9d 6f 3e 解码字节:85 62 90 c1 解码密码:?b?A
密码实际上是“abcd”