杰瑞科技汇

Java字符串如何转为BCD码?

Of course! The term "Java String BCD" refers to the process of converting a Java String to and from Binary-Coded Decimal (BCD).

Java字符串如何转为BCD码?-图1
(图片来源网络,侵删)

Let's break this down.

What is BCD?

Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually 4 bits.

  • Why use BCD? It's useful in systems where you need to interface with humans or devices that expect decimal numbers. For example, financial systems, digital clocks, and some communication protocols.
  • How it works:
    • 0 -> 0000
    • 1 -> 0001
    • 9 -> 1001
    • Numbers from 10 (1010) to 15 (1111) are invalid in standard BCD.

Example: The decimal number 1234 in BCD would be: 0001 0010 0011 0100


Key Scenarios for "Java String BCD"

When you talk about converting a Java String to BCD, there are two common interpretations:

Java字符串如何转为BCD码?-图2
(图片来源网络,侵删)
  1. String to BCD Bytes: Convert the characters of the string into a sequence of BCD-encoded bytes. This is the most common use case.
  2. String to BCD Number: Convert the string (which represents a number) into a numeric type like long or BigInteger, and then represent that number in BCD format.

We will focus on the first, more common scenario.

Scenario 1: Converting a Java String to BCD Bytes

Here, you take each character of the string, check if it's a valid digit, convert it to its 4-bit BCD value, and pack these values into bytes.

Logic:

  1. Iterate through each character of the input String.
  2. For each character, convert it to its numeric value (e.g., '5' -> 5).
  3. Check if the numeric value is between 0 and 9. If not, it's an invalid BCD digit.
  4. Pack two of these 4-bit BCD digits into a single byte:
    • The first digit goes into the high nibble (the left 4 bits).
    • The second digit goes into the low nibble (the right 4 bits).
  5. If the string has an odd number of digits, the last digit will be packed into the low nibble of the final byte, and the high nibble is typically set to 0 (or 0xF for "packed" BCD, depending on the convention).

Example Code: String to BCD Bytes

This utility class provides two static methods: one to convert a String to a byte[] and another to convert it back.

import java.nio.charset.StandardCharsets;
public class BcdUtils {
    /**
     * Converts a String containing only digits to a BCD-encoded byte array.
     *
     * @param str The numeric string to convert (e.g., "1234").
     * @return A byte array where each byte contains two BCD digits.
     * @throws IllegalArgumentException if the string contains non-digit characters.
     */
    public static String bcdToString(byte[] bcd) {
        if (bcd == null || bcd.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder(bcd.length * 2);
        for (byte b : bcd) {
            // Extract the high nibble
            int highNibble = (b & 0xF0) >>> 4;
            sb.append(highNibble);
            // Extract the low nibble
            int lowNibble = b & 0x0F;
            sb.append(lowNibble);
        }
        return sb.toString();
    }
    /**
     * Converts a BCD-encoded byte array back to a String.
     *
     * @param bcd The BCD-encoded byte array.
     * @return The original numeric string.
     */
    public static byte[] stringToBcd(String str) {
        if (str == null || str.isEmpty()) {
            return new byte[0];
        }
        // Check if the string contains only digits
        if (!str.matches("\\d+")) {
            throw new IllegalArgumentException("String must contain only digits.");
        }
        int len = str.length();
        byte[] bcd = new byte[(len + 1) / 2];
        for (int i = 0; i < len; i++) {
            int digit = Character.getNumericValue(str.charAt(i));
            // Check for valid BCD digit
            if (digit < 0 || digit > 9) {
                throw new IllegalArgumentException("Invalid BCD digit: " + digit);
            }
            if (i % 2 == 0) {
                // Even index: place digit in the high nibble
                bcd[i / 2] = (byte) (digit << 4);
            } else {
                // Odd index: place digit in the low nibble
                bcd[i / 2] |= digit;
            }
        }
        return bcd;
    }
    // --- Main method for demonstration ---
    public static void main(String[] args) {
        String originalNumber = "1234567890";
        System.out.println("Original String: " + originalNumber);
        // 1. Convert String to BCD bytes
        byte[] bcdData = stringToBcd(originalNumber);
        System.out.println("BCD Byte Array Length: " + bcdData.length);
        System.out.print("BCD Bytes: ");
        for (byte b : bcdData) {
            System.out.printf("%02X ", b); // Print as two-digit hex for clarity
        }
        System.out.println("\n");
        // 2. Convert BCD bytes back to String
        String recoveredString = bcdToString(bcdData);
        System.out.println("Recovered String: " + recoveredString);
        // Verify
        System.out.println("Conversion successful? " + originalNumber.equals(recoveredString));
    }
}

Output of the main method:

Original String: 1234567890
BCD Byte Array Length: 5
BCD Bytes: 12 34 56 78 90 
Recovered String: 1234567890
Conversion successful? true

Scenario 2: Handling Strings with Odd Lengths

The code above handles odd-length strings correctly. Let's see how:

Java字符串如何转为BCD码?-图3
(图片来源网络,侵删)
  • Input: "123"
  • Length: 3 (odd)
  • byte[] size: (3 + 1) / 2 = 2
  • Process:
    • i=0: digit=1. bcd[0] becomes 0001 0000.
    • i=1: digit=2. bcd[0] becomes 0001 0010.
    • i=2: digit=3. bcd[1] becomes 0011 0000.
  • Resulting byte[]: {0x12, 0x30}
  • Recovery:
    • Byte 0x12 -> 1 and 2
    • Byte 0x30 -> 3 and 0 (high nibble is 3, low nibble is 0)
    • Recovered String: "1230"

This is a common convention. If you want to avoid the trailing zero, you would need to pass the original length along with the BCD data or use a different packing scheme.

When to Use This?

  • Financial Protocols: Systems like SWIFT, credit card processing (EMV), and banking networks often use BCD for numeric data to avoid floating-point inaccuracies and for easy parsing.
  • Legacy Systems: Older mainframe systems and hardware devices frequently use BCD.
  • Digital Displays: Driving 7-segment displays often involves sending BCD values.

Libraries

For production code, consider using a well-tested library like Apache Commons Lang. While it doesn't have a direct String <-> BCD method, its NumberUtils and conversion utilities can be a good starting point, or you can use a more specialized financial/protocol library.

Important Note on Encoding: The BCD conversion shown here is purely a mathematical data transformation. It is not a character encoding like UTF-8 or ASCII. You cannot use new String(bcdData, "BCD") or bcdString.getBytes("BCD"). You must use a utility function like the ones above.

分享:
扫描分享到社交APP
上一篇
下一篇