30 Stimmen

byte[] zu BigInteger ohne Vorzeichen?

Motivation: Ich möchte Hashes (MD5/SHA1 usw.) in dezimale Ganzzahlen konvertieren, um Strichcodes in Code128C zu erstellen. Der Einfachheit halber ziehe ich es vor, dass alle resultierenden (großen) Zahlen positiv sind.

Ich bin in der Lage, Byte[] in BigInteger in C# zu konvertieren...
Ein Beispiel von dem, was ich bisher habe:

byte[] data;
byte[] result;
BigInteger biResult;

result = shaM.ComputeHash(data);
biResult = new BigInteger(result);

Aber (rostige CS hier) bin ich richtig, dass ein Byte-Array kann immer auf zwei Arten interpretiert werden:

  • (A): als vorzeichenbehaftete Zahl
  • (B): als eine Zahl ohne Vorzeichen

Ist es möglich, eine UNSIGNED BigInteger aus einem Byte[] in C# zu machen?

Sollte ich einfach ein 0x00 (Null-Byte) vor das Byte[] setzen?

EDIT : Vielen Dank an AakashM, Jon und Adam Robinson, anhängend ein Null-Byte hat das erreicht, was ich brauchte.

EDIT2: Ich hätte vor allem die detaillierte Dokumentation des BigInteger(byte[])-Konstruktors lesen sollen, dann hätte ich die Abschnitte über die Beschränkung auf positive Zahlen durch Anhängen des Null-Bytes gesehen.

39voto

Jon Punkte 411383

El Bemerkungen zum BigInteger Konstrukteur angeben, dass Sie sicherstellen können, dass alle BigInteger erstellt aus einer byte[] ist vorzeichenlos, wenn Sie eine 00 Byte an das Ende des Arrays bevor Sie den Konstruktor aufrufen.

Anmerkung: Die BigInteger Konstruktor erwartet, dass das Array in Little-Endian-Reihenfolge vorliegt. Behalten Sie das im Hinterkopf, wenn Sie erwarten, dass die resultierende BigInteger einen bestimmten Wert zu haben.

8voto

Mike K. Punkte 71

Seit .NET Core 2.1, BigInteger hat eine Konstrukteur mit einem optionalen Parameter isUnsigned :

public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);

6voto

AakashM Punkte 60642

Prüfung von die Dokumentation für den jeweiligen BigInteger Konstrukteur sehen wir:

Die einzelnen Bytes des Wertes Array sollten in Little-Endian Reihenfolge, vom niedrigstwertigen Byte bis höchstwertigem Byte

[...]

Der Konstruktor erwartet positive Werte im Byte-Array, um die Vorzeichen-und-Magnitude-Darstellung, und negative Werte die Zweierkomplement Komplement-Darstellung. In anderen Wenn also das höchstwertige Bit des höchstwertigen Bytes in value gesetzt ist, ist der resultierende BigInteger-Wert negativ . Abhängig von der Quelle des des Byte-Arrays kann dies zu einer positiver Wert als negativer Wert fehlinterpretiert negativen Wert fehlinterpretiert werden.

[...]

Um zu verhindern positive Werte nicht als als negative Werte fehlinterpretiert werden, können Sie können Sie einen Null-Byte-Wert an die fin des Arrays.

6voto

divieira Punkte 845

Wie andere Antworten darauf hingewiesen haben, sollten Sie ein 00-Byte an das Ende des Arrays anhängen, um sicherzustellen, dass die resultierende BigInteger positiv ist.

Nach Angaben der die BigInteger-Struktur (System.Numerics) MSDN-Dokumentation

Um zu verhindern, dass der BigInteger(Byte[])-Konstruktor die Zweierkomplement-Darstellung eines negativen Wertes mit der Vorzeichen- und Betragsdarstellung eines positiven Wertes verwechselt, sollten positive Werte, bei denen das höchstwertige Bit des letzten Bytes im Byte-Array normalerweise gesetzt wäre, ein zusätzliches Byte enthalten, dessen Wert 0 ist.

Hier ist der Code dafür:

byte[] byteArray;
// ...
var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray());

4voto

Adam Robinson Punkte 176996

Aber (rostige CS hier) bin ich richtig, dass ein Byte-Array kann immer auf zwei Arten interpretiert werden: A: als eine Zahl mit Vorzeichen B: als eine Zahl ohne Vorzeichen

Richtig ist vielmehr, dass alle Zahlen (aufgrund ihrer Speicherung im Computer) im Grunde eine Reihe von Bytes sind, was ein Byte-Array ist. Es ist nicht richtig, dass ein Byte-Array immer als vorzeichenbehaftete oder vorzeichenlose Version eines bestimmten numerischen Typs interpretiert werden kann, da nicht alle numerischen Typen vorzeichenbehaftete und vorzeichenlose Versionen haben. Fließkommatypen haben im Allgemeinen nur vorzeichenbehaftete Versionen (es gibt keine udouble o ufloat ), und in diesem speziellen Fall gibt es keine unsignierte Version von BigInteger .

Mit anderen Worten: Nein, es ist nicht möglich, aber da BigInteger einen beliebig großen Integer-Wert darstellen kann, geht kein Bereich verloren, weil er vorzeichenbehaftet ist.

Was Ihre zweite Frage betrifft, so müssten Sie Folgendes anhängen 0x00 zu beenden fin des Arrays, da die BigInteger Konstrukteur parst die Werte in Little-Endian-Byte-Reihenfolge.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X