All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.oer.BitBuilder Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for ASN.1 extension and utility APIs used to support bcpkix and bctls with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.

There is a newer version: 2.0.3
Show newest version
package org.bouncycastle.oer;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;

import org.bouncycastle.util.Arrays;

public class BitBuilder
{
    private static final byte[] bits = new byte[]{(byte)128, 64, 32, 16, 8, 4, 2, 1};


    byte[] buf = new byte[1];
    int pos = 0;

    /**
     * write a bit
     *
     * @param bit where 0 = 0 bit and not zero is 1 bit.
     * @return
     */
    public BitBuilder writeBit(int bit)
    {

        if (pos / 8 >= buf.length)
        {
            byte[] newBytes = new byte[buf.length + 4];
            System.arraycopy(buf, 0, newBytes, 0, pos / 8);
            Arrays.clear(buf);
            buf = newBytes;
        }

        if (bit == 0)
        {
            buf[pos / 8] &= ~bits[pos % 8];
        }
        else
        {
            buf[pos / 8] |= bits[pos % 8];
        }
        pos++;

        return this;
    }

    public BitBuilder writeBits(long value, int start)
    {

        for (int p = start - 1; p >= 0; p--)
        {
            int set = (value & (1L << p)) > 0 ? 1 : 0;
            writeBit(set);
        }

        return this;
    }

    public BitBuilder writeBits(long value, int start, int len)
    {

        for (int p = start - 1; p >= start - len; p--)
        {
            int set = (value & (1L << p)) != 0 ? 1 : 0;
            writeBit(set);
        }

        return this;
    }


    public int write(OutputStream outputStream)
        throws IOException
    {

        int l = (pos + (pos % 8)) / 8;
        outputStream.write(buf, 0, l);
        outputStream.flush();
        return l;
    }

    public int writeAndClear(OutputStream outputStream)
        throws IOException
    {

        int l = (pos + (pos % 8)) / 8;
        outputStream.write(buf, 0, l);
        outputStream.flush();
        zero();
        return l;
    }


    public void pad()
    {
        pos = pos + pos % 8;
    }


    public void write7BitBytes(int value)
    {

        // Skip leading zero bytes.
        boolean writing = false;
        for (int t = 4; t >= 0; t--)
        {
            if (!writing && (value & 0xFE000000) != 0)
            {
                writing = true;
            }
            if (writing)
            {
                writeBit(t).writeBits(value, 32, 7);
            }
            value <<= 7;
        }
    }

    public void write7BitBytes(BigInteger value)
    {
        int size = ((value.bitLength() + value.bitLength() % 8) / 8);
        BigInteger mask = BigInteger.valueOf(0xFE).shiftLeft(size * 8);


        // Skip leading zero bytes.
        boolean writing = false;
        for (int t = size; t >= 0; t--)
        {
            if (!writing && (value.and(mask)).compareTo(BigInteger.ZERO) != 0)
            {
                writing = true;
            }
            if (writing)
            {
                BigInteger b = value.and(mask).shiftRight(8 * size - 8);
                writeBit(t).writeBits(b.intValue(), 8, 7);
            }
            value = value.shiftLeft(7);
        }
    }

    public void zero()
    {
        Arrays.clear(buf);
        pos = 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy