BigInteger til byte[]

Jeg har brug for at konvertere et Java – BigInteger eksempel til dens værdi i bytes. Fra API, får jeg denne metode toByteArray(), der returnerer en byte [], som indeholder den to-komplement repræsentation af denne BigInteger.

Da alle mine numre er positive 128 bits (16 bytes) integer, jeg ikke har brug for den 2-komplement form, der giver mig en 128 bits + fortegn bit (129-bit)…

Er der en måde at få standard (uden 2-komplement form) repræsentation direkte fra en BigInteger?

Hvis ikke, hvordan kan jeg lige skiftet hele byte[17] array til at miste tegn smule for at få en byte[16] array?

I form af at flytte bits, jeg antager at du har læst op på <<<, <<, >>, >>> operatorer i Java?
Næsten; der er ingen <<< operatør i Java.
Hvis antallet er underskrevet, underskrevet smule, vil være 0. Er der en grund til, du har brug for at tabe en førende 0? Hvorfor ikke bare ignorere det?
Lige som du er! Ønsketænkning fra min side ;p
128 bits er 6 bytes? Er du sikker?

OriginalForfatteren Kami | 2010-12-10

3 svar

  1. 26

    Du behøver ikke at skifte. Tegnet bit er den mest betydningsfulde (= venstre) bit af din byte-array. Da du kender dine tal, vil altid være positiv, men det er garanteret til at være 0. Men serien som helhed er højrestillet.

    Så der er to tilfælde: din venstre-mest 0x00 byte er eller ikke er. Hvis det er 0x00 kan du sikkert slippe det:

    byte[] array = bigInteger.toByteArray();
    if (array[0] == 0) {
        byte[] tmp = new byte[array.length - 1];
        System.arraycopy(array, 1, tmp, 0, tmp.length);
        array = tmp;
    }

    Hvis det ikke er 0, så kan du ikke slippe det, men dit array, vil allerede være i den repræsentation, du ønsker, så du behøver ikke at gøre noget.

    Ovenstående kode skal arbejde for begge tilfælde.

    SÅ bruger romersk-nikitchenko har påpeget, at hele kroppen af if kan forenkles til en enkelt linje: array = Arrays.copyOfRange(array, 1, array.length);. Med den variation, der er ingen grund til at erklære en tmp array. Det er en stor tip, tak for det! 🙂
    Det er ikke erklæret, men det er stadig bygget, så det “kun” fører til bedre læsbar kode, ingen ydeevne. Læsbarhed er helt sikkert noget, du ønsker at har selv, derfor anførselstegnene. Bemærk, at du har brug for mere-kode hvis du vil oprette en statisk størrelse array (som i I2OSP funktion bruges til RSA osv.).
    God kommentar. En anden grund til at bruge en eksisterende bibliotek funktion snarere end din egen gennemførelse er naturligvis, at de tidligere har sandsynligvis været bredt afprøvet. For et lille stykke kode som denne kan dette ikke være så relevante, og helt sikkert, du stadig kan skrue op i, hvordan du kalde det bibliotek metode. Læsbarheden bør i hvert fald blive holdt i tankerne så godt, men det vel nok ligger i, at i øjet af beskueren: nogle kan finde aktiveringen af et godt navn metode mere læsevenlig, mens andre foretrækker måske mere udtrykkelige regler, for eksempel, hvis de har aldrig stødt på den copyOfRange metode før.
    Mens jeg har set denne kode i flere projekter, der hævder at vende tilbage unsigned-Byte-array jeg vil gerne forstå, hvis koden ovenfor virkelig returnerer unsigned-byte-array. Lad os antage, at venstre, de fleste 0x00 byte er, når vi fjerner det så, hvor er garantien for, at den næste byte byte array dvs den anden fra venstre til højre er ikke negativ, det vil sige at tilmelde bit i en byte er ikke sat til “1”. I dette tilfælde, hvis vi forsøger at konstruere en stor heltal fra new byte array, vil vi få helt andet nummer. Således spørgsmålet om, hvorfor det er sikkert at droppe venstre byte, hvis det er 0x00.
    Bemærk venligst, andet afsnit, i Kami ‘ s oprindelige spørgsmål: “[…] alle mine numre er positive […]”.

    OriginalForfatteren Thomas

  2. 4

    Det første (vigtigste) byte byte array kan ikke bare indeholder de tegn smule, men normale bits.

    E. g. dette BigInteger:

    new BigInteger("512")
        .add(new BigInteger("16"))
        .add(new BigInteger("1"));

    har denne bit mønster:
    00000010 00010001

    Der er at sige den øverste byte (med tegnet bit), har også ‘normale’ bits, som du ville forvente.

    Så hvad ønsker du at få tilbage?

    00000010 00010001 (what you have) or
    00000100 0010001? or
    10000100 01??????

    OriginalForfatteren daveb

  3. 3

    Du kan kopiere væk den første byte. Eller kan du bare ignorere det.

    BigInteger bi = BigInteger.ONE.shiftLeft(127);
    byte[] bytes1 = bi.toByteArray();
    System.out.println(Arrays.toString(bytes1));
    byte[] bytes = new byte[bytes1.length-1];
    System.arraycopy(bytes1, 1, bytes, 0, bytes.length);
    System.out.println(Arrays.toString(bytes));

    OriginalForfatteren Peter Lawrey

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *