Bitcoin VarInt data type decodering stappen met code voorbeelden!

Volgen en delen nu!

De meeste velden van de Bitcoin datastructuren hebben een vaste grootte van byte. Dat is een eenvoudige manier, maar elk veld moet het maximum aantal bytes reserveren, zelfs als u het minst mogelijke aantal hoeft te tellen. Bitcoin definieert een heel eenvoudig te begrijpen codering voor getallen, om byte te besparen op getallen die erg groot kunnen zijn, maar waarschijnlijk klein zijn. Dit gegevenstype heet een VarInt. De perfecte codering bestaat niet, het is gewoon mogelijk om te werken met waarschijnlijkheid. Het resultaat baserende strikte op de echte gegevens die normaal slechts gedeeltelijk voorspelbaar zijn. Voer de volgende stappen uit om een VarInt te decoderen:

Decoderen Bitcoin VarInt:

  1. Als de eerste byte niet 0xFD, 0xFE of 0xFF, respectievelijk (decimale niet-ondertekende 253, 254 of 255), de VarInt is slechts deze enkele byte.
  2. Als de eerste byte 0xFD, de volgende twee byte zijn de VarInt in Little Endian orde, dus de eerste byte is de onderste.
  3. Als de eerste byte 0xFE, lees de volgende vier byte in Little Endian.
  4. En hetzelfde voor 0xFF en acht bytes.

Java Bitcoin VarInt voorbeeld:

In het onderstaande voorbeeld wordt het lezen en schrijven van een VarInt als hulpprogrammamethoden geïmplementeerd. De schrijf voortgang neemt een long gegevenstype, maar schrijft altijd het laagste aantal bytes dat nodig is, zelfs wanneer u negatieve getallen gebruikt. Deze Lees methoden aan de andere kant lezen de VarInt en retourneren ze als een teken-Extended long. Vandaar dat de verwachte retourwaarde van de byte 0xFC is 0xFFFF_FFFF_FFFF_FFFCNiet 0x0000_0000_0000_00FC in grote endian orde.

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class BitcoinUtils {
  private BitcoinUtils() {
    throw new UnsupportedOperationException("Should never reaches");
  }
  
  /**
   * @param in The Stream to read the VarInt from
   * @return The VarInt sign-extended. So if the value 0xB00B, the returned
   * long is 0xFFFF_FFFF_FFFF_B00B
   * @throws IOException If the stream throws an error
   */
  public static long readVarInt(final InputStream in) throws IOException {
    final int b = in.read();
    
    if((b & 0xFFFF_FF00) != 0) {
      throw new EOFException("Unexcepted EOF");
    }
    
    // Sign-extend the return value by casting
    switch(b) {
      case(0xFD):
        final short c = readShortLittleEndian(in);
        // Correct FD to FF to Byte size
        switch(c) {
          case(0xFD):
          case(0xFE):
          case(0xFF):
            return((long)((byte)c));
        }
        return(((long)c));
      case(0xFE):
        return(((long)readIntLittleEndian(in)));
      case(0xFF):
        return(readLongLittleEndian(in));
    }
    return((long)((byte)b));
  }
  public static short readShortLittleEndian(final InputStream in) throws IOException {
    return (short) (readMultibyteNumberLittleEndian(in, 2));
  }
  public static int readIntLittleEndian(final InputStream in) throws IOException {
    return (int) (readMultibyteNumberLittleEndian(in, 4));
  }
  public static long readLongLittleEndian(final InputStream in) throws IOException {
    return(readMultibyteNumberLittleEndian(in, 8));
  }
  public static long readMultibyteNumberLittleEndian(final InputStream in, final int len)
      throws IOException {
    if(len <= 0) {
      throw new IllegalArgumentException("len <= 0");
    }
    
    long l = 0;
    for(long i = 0, j = in.read(); i < len; i++, j = in.read()) {
      if((j & 0xFFFF_FF00) != 0) {
        // return(-1);
        throw new IllegalArgumentException("Unexpected EOF");
      }
      l|= (j << (i << 3));
    }
    return(l);
  }

  /**
   * @param out The Stream to write the VarInt too.
   * @param l The long to write. It writes exactly as much bytes as need,
   * even for negativ numbers.
   * @throws IOException
   */
  public static void writeVarInt(final OutputStream out,
      final long l) throws IOException {
    // If the number is negative and a part just the sign-extends, reset
    // all sign-extending bytes to write it like an unsigned of the smaller
    // type.
    for(long mask = 0xFFFF_FFFF_FFFF_FF00L, i = 0; mask != 0; i++,
        mask<<= (i << 3)) {
      if((l & mask) == mask) {
        writeVarInt(out, l & (~mask));
        return;
      }
    }
    
    if((l & 0x8000_0000_0000_0000L) == 0) { // If positive...
      if(l <= 0xFC) {
        out.write((byte)l);
        return;
      } else if(l <= 0xFFFF) {
        out.write(0xFD);
        
        out.write((byte)l);
        out.write((byte)(l >> 8));
        return;
      } else if(l <= 0x0000_0000_FFFF_FFFFL) {
        out.write(0xFE);
        
        out.write((byte)l);
        out.write((byte)(l >> 8));
        out.write((byte)(l >> 16));
        out.write((byte)(l >> 24));
        return;
      }
    }
    
    out.write(0xFF);
    out.write((byte)l);
    out.write((byte)(l >> 8));
    out.write((byte)(l >> 16));
    out.write((byte)(l >> 24));
    
    out.write((byte)(l >> 32));
    out.write((byte)(l >> 40));
    out.write((byte)(l >> 48));
    out.write((byte)(l >> 56));
  }	
  public static void writeShortLittleEndian(final OutputStream out,
      final short s) throws IOException {
    writeMultibyteNumberLittleEndian(out, 2, s);
  }
  public static void writeIntLittleEndian(final OutputStream out,
      final int i) throws IOException {
    writeMultibyteNumberLittleEndian(out, 4, i);
  }
  public static void writeLongLittleEndian(final OutputStream out,
      final long l) throws IOException {
    writeMultibyteNumberLittleEndian(out, 8, l);
  }
  public static void writeMultibyteNumberLittleEndian(final OutputStream out,
      final int size,
      final long i) throws IOException {
    if(out == null) {
      throw new IllegalArgumentException("out == null");
    } else if(size <= 0) {
      throw new IllegalArgumentException("len <= 0");
    }
    
    for(int j = 0; j < size; j++) {
      out.write(((byte)(i >> (j << 3))));
    }
  }
}

 

 

Plaats uw reactie hier

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd *

Gratis Demo!

Toetreden tot het Calloway Crypto systeem nu,
om een gratis demo-account:

Join the Calloway Crypto Soft now!

Lees nu de hele beoordeling!

Hebt u aanvullende vragen of struikelen, stuur een email naar direct naar earnmoneytodayblog@gmail.com of gebruik de simpele Contact Formulier.

 

verdienen-money.today succesvolle uitdaging: 1041/2000 succesvolle handelaar. Test nu Calloway Crypto systeem of andere geverifieerde handelssystemen kostenloos en stuur ons hoe succesvol je bent en hoeveel winst je gemaakt, en kan wat wij voor u kunnen doen.

52%

Laatste succesvolle handelaar:
Antje B.
Worden de volgende!