Compresión de cuerdas cortas realmente simple

¿Existe una técnica de compresión realmente simple para cadenas de hasta 255 caracteres de longitud (sí, estoy comprimiendo URL )?

No me preocupa la fuerza de la compresión: estoy buscando algo que funcione muy bien y sea rápido de implementar. Me gustaría algo más simple que SharpZipLib : algo que se puede implementar con un par de métodos cortos.

Creo que la pregunta clave aquí es ” ¿Por qué quieres comprimir URL?

¿Intenta acortar las URL largas para la barra de direcciones?

Es mejor almacenar la URL original en alguna parte (base de datos, archivo de texto …) junto con un código hash de la parte que no pertenece al dominio (MD5 está bien). A continuación, puede tener una página simple (o un HTTPModule si se siente llamativo) para leer el MD5 y buscar la URL real. Así es como TinyURL y otros trabajan.

Por ejemplo:

http://mydomain.com/folder1/folder2/page1.aspx 

Podría tener un cortocircuito a:

 http://mydomain.com/2d4f1c8a 

Usar una biblioteca de compresión para esto no funcionará . La cadena se comprimirá en una representación binaria más corta, pero convertirla de nuevo en una cadena que necesita ser válida como parte de una URL (por ejemplo, Base64) anulará cualquier beneficio que haya obtenido de la compresión.

¿Almacena muchas URL en la memoria o en el disco?

Utilice la biblioteca integrada de compresión dentro de System.IO.Compression o la biblioteca ZLib que es simple e increíblemente buena. Como almacenará datos binarios, la salida comprimida estará bien tal como está. Deberá descomprimirlo para usarlo como una URL.

Como se sugiere en la respuesta aceptada , el uso de la compresión de datos no funciona para acortar las rutas de URL que ya son bastante cortas.

DotNetZip tiene una clase DeflateStream que expone un método CompressString estático (Shared in VB). Es una forma de una línea para comprimir una cadena usando DEFLATE ( RFC 1951 ). La implementación DEFLATE es totalmente compatible con System.IO.Compression.DeflateStream , pero DotNetZip se comprime mejor. Así es cómo puede usarlo:

 string[] orig = { "folder1/folder2/page1.aspx", "folderBB/folderAA/page2.aspx", }; public void Run() { foreach (string s in orig) { System.Console.WriteLine("original : {0}", s); byte[] compressed = DeflateStream.CompressString(s); System.Console.WriteLine("compressed : {0}", ByteArrayToHexString(compressed)); string uncompressed = DeflateStream.UncompressString(compressed); System.Console.WriteLine("uncompressed: {0}\n", uncompressed); } } 

Usando ese código, aquí están los resultados de mi prueba:

 original : folder1/folder2/page1.aspx compressed : 4bcbcf49492d32d44f03d346fa0589e9a9867a89c5051500 uncompressed: folder1/folder2/page1.aspx original : folderBB/folderAA/page2.aspx compressed : 4bcbcf49492d7272d24f03331c1df50b12d3538df4128b0b2a00 uncompressed: folderBB/folderAA/page2.aspx 

De modo que puede ver que la matriz de bytes “comprimidos”, cuando se representa en hex, es más larga que la original, aproximadamente 2 veces más larga. La razón es que un byte hexadecimal es realmente 2 caracteres ASCII.

Podrías compensar algo por eso usando base-62, en lugar de base-16 (hex) para representar el número. En ese caso, az y AZ también son dígitos, lo que le da 0-9 (10) + az (+26) + AZ (+26) = 62 dígitos en total. Eso acortaría la producción significativamente. No he intentado eso. todavía.


EDITAR
Ok, probé el codificador Base-62. Acorta la cuerda hexagonal a la mitad. Pensé que lo reduciría al 25% (62/16 = ~ 4) Pero creo que estoy perdiendo algo con la discretización. En mis pruebas, la cadena codificada en base 62 resultante tiene aproximadamente la misma longitud que la URL original. Entonces, no, usar la compresión y luego la encoding de la base-62 todavía no es un buen enfoque. realmente quieres un valor hash

Sugeriría buscar en el espacio de nombres System.IO.Compression . Hay un artículo en CodeProject que puede ayudar.

¿Cual es tu meta?

  • ¿Una URL más corta? Pruebe los acortadores de URL como http://tinyurl.com/ o http://is.gd/
  • ¿Espacio de almacenamiento? Mira System.IO.Compression. (O SharpZipLib )

Comenzaría probando una de las bibliotecas zip existentes (libres o de código abierto), por ejemplo, http://www.icsharpcode.net/OpenSource/SharpZipLib/

Zip debería funcionar bien para cadenas de texto, y no estoy seguro si vale la pena implementar un algoritmo de compresión yourserlf ….

¿Has intentado solo usar gzip ?

No tengo idea de si funcionaría de manera efectiva con tan pocas cadenas, pero diría que es probablemente la mejor opción.

La biblioteca de código abierto SharpZipLib es fácil de usar y le proporcionará herramientas de compresión

Puede usar el algoritmo desinflar directamente, sin ningún encabezado con sums de comprobación o pies de página, como se describe en esta pregunta: Python: inflar y desinflar implementaciones

Esto reduce una URL de 4100 caracteres a 1270 caracteres base64, en mi prueba, lo que permite que quepa dentro del límite de 2000 de IE.

Y aquí hay un ejemplo de una URL de 4000 caracteres , que no se puede resolver con una tabla hash, ya que la aplicación puede existir en cualquier servidor.

Acabo de crear un esquema de compresión que se dirige a las URL y logra una compresión de alrededor del 50% (en comparación con la representación en base64 del texto original de la URL).

ver http://blog.alivate.com.au/packed-url/