2011-02-02 13 views
29

Sto cercando l'implementazione JavaScript degli algoritmi di gonfiaggio delle stringhe. Voglio comprimere sul lato server (Java) e decomprimere sul lato client (JavaScript).JavaScript: decomprimere/gonfiare/decomprimere/stringhe ungzip

ho trovato:

unzip strings in javascript
Quello è contrassegnato come risposto con una risposta per problema diverso. Altre risposte sono anche per qualcos'altro (decomprimere file in formato ZIP).

JavaScript inflate implementation (possibly FF 3.6 only)
Questo è il più vicino a ciò di cui ho bisogno. Comunque mi piacerebbe avere alcune alternative.

Suggerimenti?
Grazie, Ondra

Aggiornamento: ho un bel caso uso specifico, si prega di non rispondere "Non lo fare in JavaScript." Sto scrivendo uno strumento di segnalazione "offline" (una volta generato, viene messo in un archivio statico) e lo sgonfiamento può far risparmiare megabyte per un singolo report. Sono limitato da altre app, quindi non posso memorizzarlo come file zip.

+3

Il problema principale sta nel fatto che JavaScript non ha strutture per la manipolazione dei dati grezzi. Tutti i numeri sono a virgola mobile e tutti i valori di stringa vengono mantenuti come UTF-16 (caratteri a 2 byte). Non esiste un tipo di dati "array di byte", quindi l'implementazione della compressione/decompressione è molto più difficile e molto meno efficiente. – Pointy

+4

Non è vero, esiste il supporto per i dati binari nelle recenti implementazioni di JavaScript, basate su [Typed Array Specification] (http://www.khronos.org/registry/typedarray/specs/latest/). –

+0

sì è vero - sarebbe certamente utile :-) – Pointy

risposta

9

Dai uno sguardo allo this Stack Overflow question, le risposte contengono riferimenti a più motori di compressione implementati in javascript. La maggior parte di questi sono basati su LZ77.

-4

Non farlo in JavaScript. Sarebbe lento e inoltre che JS non funziona bene con i dati binari.

Basta usare la codifica di trasferimento gzip sul lato server e il browser si occuperà di decomprimerlo.

+11

Non sto chiedendo se è buono o cattivo. Sto cercando delle implementazioni. -1. –

+4

È un ottimo consiglio, @Ondra. Se vuoi fare qualcosa che è considerato una "cattiva idea" da molte persone con esperienza, dovresti spiegare le tue ragioni. – Pointy

+3

@Pointy: non sono d'accordo. Certo che hai ragione, ma se qualcuno sta chiedendo qualcosa di non ortodosso, probabilmente non è la cosa migliore da agitare semplicemente un dito scodinzolante, indipendentemente dall'esperienza. – jAndy

9

Non so come vuoi, ma mi piacciono queste implementazioni:

Il primo è più veloce rispetto al secondo, possiamo garantire di solito un server veloce, però non conosciamo le prestazioni di la macchina client. Pertanto ti consiglio di scegliere js-deflate e regolare il tuo java (lato server) per gonfiare.

https://github.com/dankogai/js-deflate

http://code.google.com/p/gzipjs/

+3

Il secondo URL (gzipjs) non ha alcun codice pubblicato da nessuna parte ... o mi manca qualcosa? –

+1

Questa dovrebbe essere la risposta accettata. – almosnow

+0

Ho cercato in giro per ore ora, ho saltato oltre questa risposta la prima volta, ma è davvero molto semplice, e una soluzione eccellente. Ho fatto un benchmark contro LZMA e sta arrivando 10 volte più veloce e con compressione comparabile! –

2

questo esempio: http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip mostra come si può fare file ZIP in Javascript. Ora, so che vuoi la compressione ZLIB o DEFLATE, piuttosto che ZIP. Tuttavia, ZIP utilizza DEFLATE e, all'interno del file .js per quell'esempio, esiste una classe InflatingReader che può INFLARE mentre legge.

La classe espone questi metodi:

readByte() 
    returns null when EOF is reached, or the value of the byte when successful. 

readToEnd() 
    returns an array of all bytes read, to EOF 

beginReadToEnd(callback) 
    async version of the above 

readBytes(n) 
    returns an array of n bytes read from the source. 

beginReadBytes(n, callback) 
    async version of the above 

è possibile utilizzare tale codice invariato se si desidera INFLATE.

Se si desidera ZLIB (aka decomprimere), quindi c'è una firma a 2 byte che è necessario leggere e convalidare prima di leggere i byte compressi e fare l'INFLATE. Basta modificare il InflatingReader per leggere e scaricare 2 byte, e farà ZLIB bene.

+0

Il primo link non è più online. – heinob

+0

sì, mi dispiace, lo so. Lavorerò per portarlo in un nuovo posto. – Cheeso

2

ho trovato un'implementazione di lavoro gonfiare qui:

http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt

Se si desidera una versione leggermente più pulito che namespace l'algoritmo, questo dovrebbe funzionare:

https://github.com/augustl/js-inflate

Tenete a mente che i dati "inflazionati" compressi con gzip sono preceduti da un'intestazione a due byte e sono suffissi con un checksum a quattro byte, che sarà necessario rimuovere prima di passare all'algoritmo.