Umwandeln byte-array in jeder base
Ich habe ein array von bytes (beliebige Länge), und ich möchte zum codieren dieses array in string mit meinem eigenen base encoder. In .NET
ist standard Base64
encoder, aber was ist, wenn ich verschlüsseln will, ist das array in Base62
, Base53
oder Base13
?
Ist es sogar möglich, erstellen Sie eine solche Universelle base encoder?
Ich weiß, ich könnte es tun, der einfache Weg, das heißt, für jedes byte reserve Feste Anzahl von Zeichen (im Falle der Base62
werden würde, wäre es 5 chars), und direkte byte->chars die Codierung, aber ich würde Platz verschwenden, als 5 Base62
chars sind in der Lage, enthalten mehr als 1 byte, aber weniger als 2 bytes.
Wie soll ich schreiben, wie ein encoder? Oder gibt es hier schon einige Klasse für diese?
Und bitte beachten Sie, dass ich brauche universal-decoder wie gut, ansonsten ist dies für mich nutzlos.
Ressourcen
Als die Lösung schon bekannt ist (verwenden Sie BigInteger
), nur würde ich gerne hier einige Ressourcen, die im Zusammenhang mit dem BigInteger
Klasse, wie es nicht verfügbar ist .NET 3.5:
Große ganze zahlen in C#
http://intx.codeplex.com/
https://svn.apache.org/repos/asf/incubator/heraldry/libraries/csharp/openid/trunk/Mono/Mono.Math/BigInteger.cs
http://www.codeproject.com/KB/cs/BigInteger_Library.aspx
http://www.codeproject.com/KB/cs/biginteger.aspx
- Können Sie erklären, wo ein
Base53
oderBase62
Codierung könnte von nutzen sein? - Übrigens
Base62
Codierung ist großartig, wenn Sie wollen umwandeln byte-array in string ohne '/' und '+' ähnliche Symbole, nur a-z, a-Z, 0-9. - 5 Basis 62 Ziffern codieren kann viel mehr als 2 bytes haben!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die Leistung nicht ein Problem ist, verwenden Sie die BigInteger Klasse in den hintergrund. Sie haben einen Konstruktor BigInteger, dass dauert byte-array, und Sie können dann manuell ausführen Schleifen der division und modulus, um die Darstellung in anderen nicht-standard-Basen.
Werfen Sie auch einen Blick auf diese.
BigInteger
Klasse, das könnte das problem lösen! Leistung ist nicht ein Problem, solange die Codierung 500 bytes Daten nicht länger als 5 Sekunden.BigInteger
ist in.NET 4.0
, aber ich brauche Lösung für.NET 3.5
. 🙁BitInteger
Lösung, ich werde wahrscheinlich einige code kann ich kompilieren in meine .exe, wie in diesem CodeProject Umsetzung. Hovewer, +1, alsBigInteger
ist tatsächlich in der Lage, dieses problem zu lösen. Und wenn niemand sonst schlägt jede andere Lösung, ich werde dabei bleiben und akzeptiere deine Antwort. Danke.Ein wenig spät zur party, aber...
Weil Ihre Spezifikation für eine beliebige Anzahl von bits, Sie müssen ein ganzzahliger Typ ist, kann mit einer beliebigen Anzahl von bits. Wenn Sie kann nicht als Ziel .NET 4.0 Sie müssen betteln, leihen oder stehlen ein BigInteger-Implementierung irgendwo (mag .NET 4.0 vielleicht).
BigInteger
Lösung.BigInteger
Fall kann vermieden werden, indem ein null-byte am Ende, um die byte-array. Für Basen größer als 256 es kann in Folge kleiner string als ein minus-Zeichen-Präfix. BigIntegers sind negativ, wenn Ihre Letzte byte ist 0x80-flag gesetzt ist.Hier ist eine Kopie von meiner blog dem ich hoffe, dass hilft, wie (und warum) ich konvertieren Base62
Derzeit arbeite ich an meiner eigenen url-shortener: konv.es. Um die kürzesten möglichen Zeichen hash der url, verwende ich die GetHashCode () - Methode der string, dann konvertieren Sie die resultierende Zahl zur Basis 62 ([0-9a-zA-Z]). Die eleganteste Lösung, die ich gefunden habe bisher, um die Konvertierung (das ist auch eine handy-dandy Beispiel einer yield return) ist:
Extra credit: re-Faktor als eine Erweiterung Methode
Können Sie inspiration aus C# - Implementierung von Base32 Umsetzung von Michael Giagnocavo.
Base64
undBase32
können die Karte direkt auf einige Anzahl von bits, 6 bei derBase64
und 3 im Falle derBase32
, aber zum BeispielBase62
nicht anzeigen zu ganze Anzahl von bits. Also ich habe keine Ahnung, wie zu konvertieren, dassBase32
Umsetzung in eine Universelle Basis-encoder.BASE64 funktioniert gut, denn 64 ist eine Potenz von 2 ist (2^6), so dass jeder Charakter hält 6-bit-Daten, 3 Byte (3 * 8 = 24 bit) werden codiert in 4 Zeichen (4 * 6 = 24). Die Codierung & decodieren können, werden unten lediglich die bit-shifting bits.
Für Basen, die nicht ausrichten, mit einer Leistung von 2 (wie Sie Ihre Basis 62 oder Base-53), Dann müssen Sie behandeln die Nachricht, die Sie versuchen, zu Kodieren als eine lange Zahl, und führen Division und modulo-Operationen. Sie wäre wahrscheinlich besser dran mit einem Base32-Kodierung und-Verschwendung ein bisschen Bandbreite.
BigInteger
Klasse oder so etwas ähnliches Klasse?Weiteres Beispiel zu betrachten ist Ascii85, verwendet Adobe PostScript-und PDF-Dokumente. In Ascii85, 5 Zeichen codiert 4 bytes. Sie können herausfinden, die Effizienz der Codierung (256^4)/(85^5) = 96.8%. Dies ist der Bruchteil von bit-Kombinationen, die tatsächlich verwendet werden.
So, was auch immer die neue Basis, die Sie verwenden möchten, um die Verschlüsselung Ihrer Daten, die Sie schauen wollen, für eine Leistung zu bekommen, die es nur über eine Leistung von 256, wenn Sie versuchen zu maximieren kodiereffizienz. Das könnte nicht leicht werden für jede Basis. Überprüfung base 53 zeigt, dass das beste werden Sie wahrscheinlich bekommen, ist mit 7 zu kodierenden bytes 5 bytes (93.6% Wirkungsgrad), es sei denn, fühlen Sie sich wie mit 88 bytes zu Kodieren, 63 bytes.
Ich geschrieben habe, ein Artikel, die beschreibt eine Lösung in Python, die genau befasst sich mit deinem problem. Ich habe nicht sehr spezielle features von Python geben, um zu bekommen eine Lösung, die einfach implementiert werden, in anderen Sprachen. Haben Sie vielleicht einen Blick und finden Sie heraus, ob es passt Ihre Bedürfnisse.
Ein post auf CodeReview mich dazu veranlasst, zu erstellen RadixEncoding Klasse, die ist in der Lage, die Codierung/Decodierung ein byte-array zu/von einem base-N string.
Die Klasse gefunden werden kann in diesem Q&A thread, zusammen mit der Dokumentation auf (und Lösungen) ein paar Grenzfälle, die beim Umgang mit BigInteger, endian-ness-Unterstützung, und die Klasse' Gesamtleistung