我在使用LINQ-to-Entities处理8位ASCII字符时遇到了有趣的问题,希望有人能给我一些提示。 我继承了一个SQL Server 2000数据库,其中有一些伪加密列,它们只是将字符串与0xFF异或。不知道为什么,我知道这很糟糕,但现在就是这样。
这些列是SQL数据类型char(7)和char(14)。当您使用0xFF进行XOR运算时,您在每种情况下都会设置第8位,因此您最终得到非ASCII(按Microsoft的定义)字符。UTF-8似乎在这里是指示符,但解码变得混乱。
我可以按以下方式读取和解码这些字符串:
1. 使用LINQ将字段作为String获取。 2. 使用System.Text.Encoding.GetEncoding(1252).GetBytes()获取一个byte []。 3. 通过对每个字节进行XOR运算来解码。 4. 使用System.Text.Encoding.GetEncoding(1252).GetString()返回解码后的字符串。
这完美地工作。
我的问题是,我似乎无法使用LINQ将编码后的字符串放回SQL Server。我基本上正在执行反向过程,并进行以下操作:
1. 使用ASCIIEncoding.GetBytes()获取字节。 (这里不需要CodePage 1252,因为这是一个直接字符串。) 2. 用0xFF编码字节。 3. 用GetEncoding(1252).GetString()返回编码后的字符串。
如果我查看我的字符串,它正是我所期望的。但是,如果我将其放入实体并执行SaveChanges(),则SQL Server中的结果值始终为某个长度的“?”。
我确定我在这里漏了什么,但我已经尝试了我能想到的一切,都无法解决它。现在,我只需回归使用SqlCommand的老方法,并使用编码后的字符串作为SqlParameters进行更新即可。没问题,在那里工作得很好。
感谢您提前提供任何帮助。
更新:
我尝试了JamieSee的建议,甚至使用他的方法也没有得到好的解码。 我有:
这些列是SQL数据类型char(7)和char(14)。当您使用0xFF进行XOR运算时,您在每种情况下都会设置第8位,因此您最终得到非ASCII(按Microsoft的定义)字符。UTF-8似乎在这里是指示符,但解码变得混乱。
我可以按以下方式读取和解码这些字符串:
1. 使用LINQ将字段作为String获取。 2. 使用System.Text.Encoding.GetEncoding(1252).GetBytes()获取一个byte []。 3. 通过对每个字节进行XOR运算来解码。 4. 使用System.Text.Encoding.GetEncoding(1252).GetString()返回解码后的字符串。
这完美地工作。
我的问题是,我似乎无法使用LINQ将编码后的字符串放回SQL Server。我基本上正在执行反向过程,并进行以下操作:
1. 使用ASCIIEncoding.GetBytes()获取字节。 (这里不需要CodePage 1252,因为这是一个直接字符串。) 2. 用0xFF编码字节。 3. 用GetEncoding(1252).GetString()返回编码后的字符串。
如果我查看我的字符串,它正是我所期望的。但是,如果我将其放入实体并执行SaveChanges(),则SQL Server中的结果值始终为某个长度的“?”。
我确定我在这里漏了什么,但我已经尝试了我能想到的一切,都无法解决它。现在,我只需回归使用SqlCommand的老方法,并使用编码后的字符串作为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"
SELECT collation_name FROM sys.databases WHERE name = 'mydatabase'
命令来查找。 - JamieSee