72 lines
2.5 KiB
Java
72 lines
2.5 KiB
Java
package com.solab.iso8583.util;
|
|
|
|
import java.math.BigInteger;
|
|
import java.text.ParseException;
|
|
|
|
/**
|
|
* Routines for Binary Coded Digits.
|
|
*
|
|
* @author Enrique Zamudio
|
|
* Date: 23/04/13 11:24
|
|
*/
|
|
public final class Bcd {
|
|
|
|
private Bcd(){}
|
|
|
|
/** Decodes a BCD-encoded number as a long.
|
|
* @param buf The byte buffer containing the BCD data.
|
|
* @param pos The starting position in the buffer.
|
|
* @param length The number of DIGITS (not bytes) to read. */
|
|
public static long decodeToLong(byte[] buf, int pos, int length)
|
|
throws IndexOutOfBoundsException {
|
|
if (length > 18) {
|
|
throw new IndexOutOfBoundsException("Buffer too big to decode as long");
|
|
}
|
|
long l = 0;
|
|
long power = 1L;
|
|
for (int i = pos + (length / 2) + (length % 2) - 1; i >= pos; i--) {
|
|
l += (buf[i] & 0x0f) * power;
|
|
power *= 10L;
|
|
l += ((buf[i] & 0xf0) >> 4) * power;
|
|
power *= 10L;
|
|
}
|
|
return l;
|
|
}
|
|
|
|
/** Encode the value as BCD and put it in the buffer. The buffer must be big enough
|
|
* to store the digits in the original value (half the length of the string). */
|
|
public static void encode(String value, byte[] buf) {
|
|
int charpos = 0; //char where we start
|
|
int bufpos = 0;
|
|
if (value.length() % 2 == 1) {
|
|
//for odd lengths we encode just the first digit in the first byte
|
|
buf[0] = (byte)(value.charAt(0) - 48);
|
|
charpos = 1;
|
|
bufpos = 1;
|
|
}
|
|
//encode the rest of the string
|
|
while (charpos < value.length()) {
|
|
buf[bufpos] = (byte)(((value.charAt(charpos) - 48) << 4)
|
|
| (value.charAt(charpos + 1) - 48));
|
|
charpos += 2;
|
|
bufpos++;
|
|
}
|
|
}
|
|
|
|
/** Decodes a BCD-encoded number as a BigInteger.
|
|
* @param buf The byte buffer containing the BCD data.
|
|
* @param pos The starting position in the buffer.
|
|
* @param length The number of DIGITS (not bytes) to read. */
|
|
public static BigInteger decodeToBigInteger(byte[] buf, int pos, int length)
|
|
throws IndexOutOfBoundsException {
|
|
char[] digits = new char[length];
|
|
int start = 0;
|
|
for (int i = pos; i < pos + (length / 2) + (length % 2); i++) {
|
|
digits[start++] = (char)(((buf[i] & 0xf0) >> 4) + 48);
|
|
digits[start++] = (char)((buf[i] & 0x0f) + 48);
|
|
}
|
|
return new BigInteger(new String(digits));
|
|
}
|
|
|
|
}
|