Link to home
Start Free TrialLog in
Avatar of chinsw
chinsw

asked on

Convert ascii to bcd(binary coded decimal) in Java

I need to send the field value in bcd format and then encode using base64. The field value consist of 40 digits (number) and how can i convert it into 20 bytes (bcd) format in java. Any body know the solution?
Avatar of Sathish David  Kumar N
Sathish David Kumar N
Flag of India image

Avatar of amitkathpal123
amitkathpal123

What i understood is you want to convert filed value (a String) into BCD format.
try baove code:
public static byte[] convertToBCD(String val) {
		BigInteger v = new BigInteger(val);
		return new BigInteger(v.abs().toString(), 16).shiftLeft(4)
			.add(BigInteger.valueOf(v.signum() < 0 ? 13L : 12L)).toByteArray();
	}

Open in new window

Avatar of chinsw

ASKER

Actually, i'm developing a messaging system to interface with Visa and they request us to make the Transaction ID field value into 20 bytes and encode using the base64. Let say, the transaction ID is "123243012334344000". What should i do in order to get the 20 bytes value?. I must pad it into 40 char and then call the above function to convert it to BCD format
There are some complexities you haven't covered - and your consuming application might be expecting sign or decimal point, and will probably expect them in a specific format. See:

http://en.wikipedia.org/wiki/Binary-coded_decimal

BUT, assuming positive integers, decimal, only, AND assuming that the string has been validated to contain decimal digits and only decimal digits, leading zeroes stripped

the following code should work:



    private static byte[] toBcd(String s) {
        int size = s.length();
        byte[] bytes = new byte[(size+1)/2];
        int index = 0;
        boolean advance = size%2 != 0;
        for ( char c : s.toCharArray()) {
            byte b = (byte)( c - '0');
            if( advance ) {
                bytes[index++] |= b;
            }
            else {
                bytes[index] |= (byte)(b<<4);
            }
            advance = !advance;
        }
        return bytes;
    }

Open in new window

Dang... three posts between when I read and posted. (sigh, the XX lag time problem again.)

based on the new reqmts, my code changes as follows (I've added a main method that tests and displays

public class BCD {
 
    private static byte[] toBcd(String s) {
        int size = s.length();
        byte[] bytes = new byte[20];
        int index = 20 - (size+1)/2;
        boolean advance = size%2 != 0;
        for ( char c : s.toCharArray()) {
            byte b = (byte)( c - '0');
            if( advance ) {
                bytes[index++] |= b;
            }
            else {
                bytes[index] |= (byte)(b<<4);
            }
            advance = !advance;
        }
        return bytes;
    }
    public static void main(String[] args) {
        byte[] ba = toBcd("12121243123");
        for ( byte b : ba ) {
            System.out.printf(" %02X",b);
        }
    }
}

Open in new window

chinsw's code does not pad out to 20 bytes and (I'm speculating here) might not perform quite as quickly as the bytearray in the long run, but otherwise that's a pretty clever algorithm.  
Padding the value is a fairly simple issue:
	byte[] ba = new BigInteger(numberString, 16).toByteArray();
	byte[] armature = new byte[20];
	System.arraycopy(ba, 0, armature, armature.length - ba.length, ba.length);
// Display only
	for ( byte b : armature) {
	    System.out.printf(" %02X",b);
	}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of chinsw

ASKER

Is it possible to convert the value in alphabet to BCD
<boggle/>
Is not that exactly what the three of us have shown you?


On second thought I guess I'm just not clear on what you are asking for. Please explain in further detail what you want - . Are you asking about rendering Java Strings as character encodings and then rendering those into BCD?. If so, which character encoding. It matters a great deal. They are all, of course, ultimately just numbers, and can be encoded as BCD. It would be better if you could be more explicit.


>>Actually, i'm developing a messaging system to interface with Visa and they request us to make the Transaction ID field value into 20 bytes and encode using the base64.

Are you now saying that the id can contain characters as well? If so, which ones, and what basic encoding do they want you to use?
Avatar of chinsw

ASKER

Complete solution
:-)