jwh*_*h20 7 linq entity-framework utf-8 codepages non-ascii-characters
我有一个有趣的问题,处理LINQ到实体中的8位"ASCII"字符,我希望有人可以给我一个提示.
我继承了一个SQL Server 2000数据库,它有一些伪加密列,它们只是对字符串进行异或0xFF
.不知道为什么,我知道它是蹩脚的,但那就是我们现在所处的位置.
这些列是SQL数据类型char(7)
和char(14)
.使用XOR时,0xFF
在每种情况下都会设置第8位,因此最终会得到非ASCII(通过Microsoft的定义)字符.似乎在这里指出了UTF-8,但是解码变得混乱了.
我能够读取和解码这些字符串如下:
String
.byte[]
使用System.Text.Encoding.GetEncoding(1252).GetBytes()
0xFF
System.Text.Encoding.GetEncoding(1252).GetString()
这非常有效.
我遇到的问题是我似乎无法使用LINQ将ENCODED字符串放回SQL Server.
我基本上遵循相反的过程并且正在做:
ASCIIEncoding.GetBytes()
.(此处不需要CodePage 1252,因为这是一个直字符串.)0xFF
.GetEncoding(1252).GetString()
.如果我看看我的字符串,这正是我所期待的.但是,如果我在我的实体中填充并SaveChanges()
在SQL Server中执行结果值总是"?????"
有一定的长度.
我确定我在这里遗漏了一些东西,但我已经尝试了所有我能想到的东西,却无法得到它.现在我只是回到了使用a SqlCommand
和使用编码字符串进行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();
}
Run Code Online (Sandbox Code Playgroud)
但结果是:
原始XOR编码PW:z?o>原始字节:7a 9d 6f 3e解码字节:85 62 90 c1解码PW:?b?A
密码实际上是"abcd"
不要使用代码页 1252,使用Encoding.GetEncoding(28591)
(iso-8859-1) 或Encoding.GetEncoding(850)
(ibm850),它们都会为您提供 8 位基于 ASCII 的字符集。
这是一些快速而肮脏的代码,您可以尝试使用不同的编码,以演示您的问题和解决方案:
public static void Main()
{
Encoding characterEncoding = Encoding.GetEncoding(28591);
string original = "This is some bogus data to test the problem.";
Console.WriteLine("Original String: {0}", original);
Console.Write("Original Bytes: ");
foreach (byte b in characterEncoding.GetBytes(original))
{
Console.Write("{0:x}", b);
}
Console.WriteLine();
byte[] encodedBytes = (from character in characterEncoding.GetBytes(original)
select (byte)(character ^ 0xFF)).ToArray();
Console.Write("Encoded Bytes: ");
foreach (byte b in encodedBytes)
{
Console.Write("{0:x}", b);
}
Console.WriteLine();
string encoded = characterEncoding.GetString(encodedBytes);
byte[] decodedBytes = (from character in characterEncoding.GetBytes(encoded)
select (byte)(character ^ 0xFF)).ToArray();
Console.Write("Decoded Bytes: ");
foreach (byte b in decodedBytes)
{
Console.Write("{0:x}", b);
}
Console.WriteLine();
string decoded = characterEncoding.GetString(decodedBytes);
Console.WriteLine("Decoded String: {0}", decoded);
}
Run Code Online (Sandbox Code Playgroud)