Ho un problema interessante che gestisce i caratteri "ASCII" a 8 bit in LINQ-to-Entities e spero che qualcuno possa darmi un consiglio.LINQ-to-Entities con dati ASCII a 8 bit
Ho ereditato un database SQL Server 2000 che contiene alcune colonne pseudo-crittografate in cui hanno appena eseguito XOR la stringa con 0xFF
. Non so perché e so che è zoppo ma è lì che siamo ora.
Queste colonne sono del tipo di dati SQL char(7)
e char(14)
. Quando XOR usa 0xFF
ottieni l'ottavo bit impostato in ogni caso, così finirai con caratteri non ASCII (comunque definiti dalla Microsoft). L'UTF-8 sembra essere indicato qui, ma la decodifica si incasina.
io sono in grado di leggere e decodificare queste stringhe come segue:
- Prendi il campo utilizzando LINQ come
String
. - Prendi un
byte[]
utilizzandoSystem.Text.Encoding.GetEncoding(1252).GetBytes()
- Decode da XOR ogni byte con
0xFF
- restituire la stringa decodificata con
System.Text.Encoding.GetEncoding(1252).GetString()
Questo funziona perfettamente.
Il problema che sto avendo è che non riesco a mettere una stringa ENCODED a SQL Server usando LINQ.
sto fondamentalmente seguendo il processo inverso e sto facendo:
- Ottenere i byte utilizzando
ASCIIEncoding.GetBytes()
. (Non c'è bisogno di CodePage 1252 qui perché questa è una stringa diritta.) - Codifica i byte con
0xFF
. - Restituisce la stringa codificata con
GetEncoding(1252).GetString()
.
Se guardo la mia stringa, è esattamente quello che mi aspetterei. Ma se lo faccio nella mia entità e faccio un SaveChanges()
il valore risultante in SQL Server è sempre "?????"
di una certa lunghezza.
Sono sicuro che mi manca qualcosa qui ma ho provato tutto quello che riesco a pensare e non riesco a capirlo. Per ora sono appena tornato al vecchio modo di usare un SqlCommand
e di fare un UPDATE con le stringhe codificate come SqlParameters
. Nessun problema, funziona sempre.
Grazie in anticipo per qualsiasi assistenza.
Aggiornamento:
Ho provato il suggerimento di JamieSee e io non sono nemmeno ottenere una buona decodifica con il suo metodo. Ho:
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();
}
Ma il risultato di che sono:
originale XOR Encoded PW: z?o> Byte originali: 7a 9d 6f 3e Decoded Bytes: 85 62 90 c1 Decoded PW: b Un
La password è in realtà "ABCD"
Si prega di catturare l'SQL eseguito da L2S utilizzando SQL Profiler e post-it. (È estremamente facile farlo.) – usr
Uso LINQ-to-Entities e non LINQ-to-SQL ma acquisire l'SQL usando Profiler è una buona idea. Lo sistemerò e vedrò cosa dice. Ma la mia ipotesi è che mostrerà che SQL sta memorizzando esattamente quello che viene detto di memorizzare. Credo davvero che il problema sia nel mappare i caratteri non ASCII da Entity FW a SQL. – user1536209
Quali sono le tue regole di confronto per il database in questione? Puoi trovarlo con 'SELECT nome_collazione FROM sys.databases WHERE name = 'mydatabase''. – JamieSee