Tengo una base de datos sql-server 2010 compartida entre dos aplicaciones. Una aplicación que tenemos control, y la otra aplicación es una aplicación de terceros que creó la base de datos en primer lugar. Nuestra aplicación es un CRM construido sobre la aplicación webmail de terceros.Detección de codificación UTF-8 incorrecta: lista de caracteres incorrectos para olfatear?
La base de datos contiene columnas varchar y está codificada en latín-1. La aplicación de terceros está escrita en php y no le importa codificar correctamente los datos, por lo que incluye bytes codificados en utf-8 en las columnas varchar, donde se interpretan como latin-1 y se ven como basura.
Nuestra aplicación CRM está escrita en .Net, que detecta automágicamente que la intercalación de la base de datos es diferente a la codificación de la cadena en la memoria, por lo que cuando .Net escribe en una base de datos, convierte los bytes para que coincidan con la codificación de la base de datos.
Entonces ... los datos escritos en la base de datos desde nuestra aplicación se ven correctos en la base de datos, pero los datos de la aplicación de terceros no.
cuando nuestra aplicación escribe Nombre = Céline, que se almacena en el PP como Céline
cuando la aplicación de correo web escribe Nombre = Céline se almacena en el PP como CÃ © line
necesidades de aplicacionesNuestro CRM para mostrar los contactos que se crearon en cualquier sistema. Así que estoy escribiendo una clase EncodingSniffer que busca caracteres marcados que indican que es una cadena mal codificada y los convierte.
Actualmente tengo:
private static string[] _flaggedChars = new string[] { "é" };
la que funciona muy bien para la visualización de CÃ © line como Céline, pero tengo que añadir a la lista.
¿Alguien sabe de un recurso para obtener todas las formas posibles en que los caracteres especiales utf-8 podrían interpretarse como iso-8859-1?
Gracias
Aclaración: Desde que estoy trabajando en .Net. La cadena, cuando se carga en la memoria de la base de datos, se convierte a Unicode UTF-16. Entonces, independientemente de si estaba codificado correctamente en la base de datos. Ahora se representa como bytes UTF16. Necesito poder analizar los bytes UTF-16, y determinar si están dañados debido a que los bytes utf-8 se rellenan en una base de datos iso-8859-1 ... claro como el barro ¿verdad?
Esto es lo que tengo hasta ahora. Se ha limpiado la pantalla de la mayoría de los caracteres mal codificados, pero todavía tengo problemas con É por ejemplo: Éric se almacena en el db por webmail como à ‰ ric, pero después de detectar la codificación incorrecta y cambiarla de nuevo, se muestra como ? ric en cuanto a un usuario que dispone de 2500, cientos de contactos que había que codifican cuestiones, el E es el único que no se muestra correctamente ...
public static Regex CreateRegex()
{
string specials = "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö";
List<string> flags = new List<string>();
foreach (char c in specials)
{
string interpretedAsLatin1 = Encoding.GetEncoding("iso-8859-1").GetString(Encoding.UTF8.GetBytes(c.ToString())).Trim();//take the specials, treat them as utf-8, interpret them as latin-1
if (interpretedAsLatin1.Length > 0)//utf-8 chars made up of 2 bytes, interpreted as two single byte latin-1 chars.
flags.Add(interpretedAsLatin1);
}
string regex = string.Empty;
foreach (string s in flags)
{
if (regex.Length > 0)
regex += '|';
regex += s;
}
return new Regex("(" + regex + ")");
}
public static string CheckUTF(string data)
{
Match match = CreateRegex().Match(data);
if (match.Success)
return Encoding.UTF8.GetString(Encoding.GetEncoding("iso-8859-1").GetBytes(data));//from iso-8859-1 (latin-1) to utf-8
else
return data;
}
Así que: E se está convirtiendo a 195' Ã ', 8240' ‰ '
es una opción para cambiar la codificación de DB a UTF-8, parece que la solución más simple ya que no hay un 1 a 1 conversión entre Unicode y latino-1 –
comprobar si la cadena es UTF válida -8 podría ser un mejor enfoque. (Probablemente también sea menos costoso) – Mat
@Mat, eso es esencialmente lo que estoy tratando de hacer, simplemente no sé cómo. y el enfoque de olfatear a los malos fue lo mejor que se me ocurrió. ¿Cómo harías para probar utf-8 válido? – Michael