Java Byte Array Create toBytesFromOct(String octSymbols)

Here you can find the source of toBytesFromOct(String octSymbols)

Description

Given a String of octal digits, return the corresponding byte array

License

Open Source License

Parameter

Parameter Description
octSymbols A string of octal digits

Return

The corresponding byte array

Declaration

public static byte[] toBytesFromOct(String octSymbols) 

Method Source Code

//package com.java2s;
//License from project: Open Source License 

public class Main {
    public final static int BITS_PER_OCT_DIGIT = 3;
    /** The regular expression for an octal string */
    public static final String OCTAL_REGEXP = "[0-7]{0,}";

    /**//from  w w  w  .j  av  a  2 s. c  om
     * Given a String of octal digits, return the corresponding byte array
     *
     * @param octSymbols
     *            A string of octal digits
     * @return The corresponding byte array
     */
    public static byte[] toBytesFromOct(String octSymbols) {
        if (octSymbols == null || octSymbols.trim().length() == 0) {
            return (new byte[0]);
        } else if (isValidOct(octSymbols) == false) {
            throw new IllegalArgumentException("Invalid octal string specified: " + octSymbols);
        }

        while (((octSymbols.length() * BITS_PER_OCT_DIGIT) % 8) != 0) {
            octSymbols = "0" + octSymbols;
        }

        // there are 3 bits per octal symbol and 8 bits in a byte
        int numBytes = (octSymbols.length() * BITS_PER_OCT_DIGIT) / 8;
        byte[] bytes = new byte[numBytes];

        // the index in the array of output bytes
        int byteArrayIndex = 0;

        // the index from 0-7 within the current byte
        int currentByteIndex = 0;

        // the current byte being output
        byte currentByte = 0x00;

        // the next byte being used
        byte nextByte = 0x00;

        // This parsing can get a little nasty because octal numbers don't split evenly into bytes, so we
        // may have to set bits in two different bytes at the same time. This is why we have to
        // keep track of the current byte and the next byte.
        //
        // Parsing octal into bytes falls into a pattern. Every three bytes the pattern repeats. The 8 scenarios in
        // the switch statement below represents the 8 possible cases that occur.

        for (int i = 0; i < octSymbols.length(); i++) {
            // transform the current octal digit into a numeric value
            int octDigit = (Integer.parseInt(octSymbols.substring(i, i + 1))) & 0x07;

            // When talking about the bits in a byte, bit 0 is the MSB and
            // bit 7 is the LSB. So for instance, bits 0-2 of current byte
            // means the 3 uppermost bits of the byte.
            switch (currentByteIndex) {
            // set bits 0-2 of current byte
            case (0):

                currentByte = (byte) (currentByte | (octDigit << 5));

                break;

            // set bits 1-3 of current byte
            case (1):

                currentByte = (byte) (currentByte | (octDigit << 4));

                break;

            // set bits 2-4 of current byte
            case (2):

                currentByte = (byte) (currentByte | (octDigit << 3));

                break;

            // set bits 3-5 of current byte
            case (3):

                currentByte = (byte) (currentByte | (octDigit << 2));

                break;

            // set bits 4-6 of current byte
            case (4):

                currentByte = (byte) (currentByte | (octDigit << 1));

                break;

            // set bits 5-7 of current byte
            case (5):

                currentByte = (byte) (currentByte | octDigit);

                break;

            // set bits 6-7 of current byte and
            // set bit 0 of next byte
            case (6):

                currentByte = (byte) (currentByte | ((octDigit & 0x06) >>> 1));
                nextByte = (byte) (nextByte | ((octDigit & 0x01) << 7));

                break;

            // set bit 7 of current byte and
            // set bits 0-1 of next byte
            case (7):

                currentByte = (byte) (currentByte | ((octDigit & 0x04) >>> 2));
                nextByte = (byte) (nextByte | ((octDigit & 0x03) << 6));

                break;

            default:
                return (null);
            }

            // if the index is 5, 6, or 7 we've moved onto the next byte
            if (currentByteIndex > 4) {
                bytes[byteArrayIndex] = currentByte;
                currentByte = nextByte;
                nextByte = 0x00;
                byteArrayIndex++;
            }

            // octal digits are 3 bits so we always increment by 3
            currentByteIndex = (currentByteIndex + BITS_PER_OCT_DIGIT) % 8;
        }

        return (bytes);
    }

    public static boolean isValidOct(final String octSymbols) {
        return (octSymbols.matches(OCTAL_REGEXP));
    }
}

Related

  1. toBytesFromASCII(final char[] chars)
  2. toBytesFromBase64(String inBase64String)
  3. toBytesFromBin(String binSymbols)
  4. toBytesFromHexStr(String hexStr)
  5. toBytesFromHexString(String digits)
  6. toBytesFromString(String s)
  7. toBytesFromUnicode(String s)
  8. toBytesHexEscaped(final byte[] s, final int off, final int len)
  9. toBytesInt32BE(int w)