2016-05-05 8 views
0

Ich habe einige Binärdaten, die ich in etwas leichter lesbar und kopieren/übersetzbar konvertieren möchte.Mit Ruby, wie binäre Daten in hochkomprimiert, aber lesbar, Format konvertieren

Die binäre Daten zeigt sich, wie diese

?Q?O?,???W%ʐ):?g???????? 

die ziemlich hässlich. Ich kann es in Hex mit:

value.unpack("H*").first 

konvertieren Aber da hexadezimal nur 16 Zeichen hat, ist es nicht sehr komprimiert. Ich lande mit einer Zeichenfolge, die Hunderte von Zeichen lang ist.

Ich würde ein Format bevorzugen, das Buchstaben (Groß- und Kleinbuchstaben), Zahlen und Grundsymbole verwendet, um die möglichen Werte bestmöglich zu nutzen. Was kann ich verwenden?

Ich würde auch etwas bevorzugen, das in Ruby integriert ist, das keine andere Bibliothek benötigt. Leider kann ich keine andere Bibliothek benötigen, es sei denn, sie ist wirklich bekannt und beliebt oder im Idealfall in Ruby integriert.

Ich probierte die Sachen von http://apidock.com/ruby/String/unpack und konnte nichts finden.

+0

Wie liest/lädt man die Binärdaten? Was ist die Quelle der Daten (z. B. ist es streaming wie über ein Netzwerk kommen oder statisch wie eine Datei?)? Wie rendern/geben Sie die Rohdaten so aus, dass sie wie folgt angezeigt werden:? Q? O?, ??? W% ʐ) :? g ???????? '? –

Antwort

1

Eine einfache Methode verwendet die Base64-Codierung, um den Wert zu codieren. Es ist der Hex-Codierung sehr ähnlich (das ist Base16), verwendet aber ein längeres Wörterbuch.

Base64-Strings enthalten bei richtiger Vorbereitung nur druckbare Zeichen. Dies ist ein Vorteil für das Kopieren/Einfügen und für das Teilen.

Der sekundäre Vorteil ist, dass es ein 3: 4-Kodierungsverhältnis hat, was bedeutet, dass es einigermaßen effizient ist. Ein 3: 4-Codierungsverhältnis bedeutet, dass für jeweils 3 Bytes in der Eingabe 4 Bytes zum Codieren verwendet werden (75% effizient); Die Hexadezimalcodierung ist ein weniger effizientes 1: 2-Codierungsverhältnis oder für jedes 1 Byte der Eingabe werden 2 Byte zum Codieren verwendet (50% effizient).

Sie können die Ruby-Standardbibliothek Base64 Implementierung verwenden zu kodieren und zu dekodieren, etwa so:

require "base64" 

encoded = Base64.encode64("Taste the thunder!") # <== "VGFzdGUgdGhlIHRodW5kZXIh\n" 
decoded = Base64.decode64(encoded)    # <== "Taste the thunder!" 

Hinweis, dass es eine (meist) URL-sichere Version ist, als auch, so dass Sie ein einschließen codierter Wert an einer beliebigen Stelle in einer URL, ohne dass eine zusätzliche URL-Codierung erforderlich ist. Dies würde es Ihnen ermöglichen, Informationen in einer URL auf verschleierte Weise weiterzuleiten, und insbesondere Informationen, die normalerweise auf diese Weise nicht einfach weitergegeben würden.

diesen Versuchen Sie, Ihre Daten zu kodieren:

encoded_url_param = Base64.urlsafe_encode64("cake+pie=yummy!") # <== "Y2FrZStwaWU9eXVtbXkh" 
decoded_url_param = Base64.urlsafe_decode64(encoded_url_param) # <== "cake+pie=yummy!" 

Base64 Verwendung in einer URL, während sie in Wirklichkeit nicht „Sicherheit“, wird dazu beitragen Augen aus Ihren Daten und die Absicht neugierig. Der einzige mögliche Nachteil bei der Verwendung von Base64-Werten in einer URL besteht darin, dass bei der URL die Groß-/Kleinschreibung beachtet werden muss, und einige Anwendungen erfüllen diese Anforderung nicht. Siehe die Should URL be case sensitive SO Frage für weitere Informationen.

1

Klingt für mich wie Sie wollen Basis 64. Es ist Teil der Standardbibliothek ist:

require 'base64' 
Base64.encode64(some_data) 

Oder Pack verwenden,

[some_data].pack("m") 

Die resultierenden Daten ist etwa 4/3 der Größe die Eingabe.

1

Base36-String-Codierung ist auch eine sinnvolle Alternative zu Base64 und Hex-Codierung. Bei dieser Kodierungsmethode werden nur 36 Zeichen verwendet, typischerweise die ASCII-Kleinbuchstaben und die ASCII-Zahlen.

Es gibt nicht ein Ruby-API, die dies ausdrücklich tut, aber dies SO Base36 Encode a String beantworten zeigt, wie dies in Ruby effizient tun:

Encoding zu Base36:

encoded = data.unpack('H*')[0].to_i(16).to_s(36) 

Decodierung von Base36:

decoded = [encoded.to_i(36).to_s(16)].pack 'H*' 

Die Base36-Codierung funktioniert gut, wenn sie in URLs verwendet wird, ähnlich wie Base64, jedoch ist sie nicht empfindlich für die Probleme mit der Groß- und Kleinschreibung, die Base 64 ist.

Beachten Sie, dass Base36-String-Codierung nicht mit Basis-36-Radix-Integer-Codierung verwechselt werden soll, die einfach einen ganzzahligen Wert in die entsprechende Base 36-Codierung konvertiert. Die Ganzzahltechnik verwendet String#to_i(36) und Fixnum#to_s(36), um ihre Ziele zu erreichen.