1

BCDデータをASCIIに変換するJavaクラスを変換しています

.NetBCDConvertorに変換しています

以下はJavaから変換されたものですが、間違った変換値を示しています。たとえば、123456789の場合は123456153153を示しています。

 public static string GetStringFromBcd(int[] b)
 {
   StringBuilder buffer = new StringBuilder();
   foreach (var t in b)
   {
     if ((t & 0x0000000F) == 0x0000000F && ((t >> 4) & 0x0000000F) == 0x0000000F)
     {
         break;
     }
     buffer.Append((t & 0x0000000F) + "");
     if ((t & 0x000000F0) != 0x000000F0)
     {
         buffer.Append(((t >> 4) & 0x0000000F) + "");
     }
   }
}

何が問題なのですか?

編集:答え:

データがBCDでエンコードされたソースプログラムを入手しました。そのロジックには何も問題がないことがわかり、データがネットワークストリームから文字列に変換され、後でbyte/int配列に変換される関数のソースを発見しました。以下はコードです

 int bytesRead = tcpClient.Receive(message);//, 0, bytetoReadSize);
 if (bytesRead == 0)
 {
     break;
     //the client has disconnected from the server
 }

 //message has successfully been received
 data += new ASCIIEncoding().GetString(message, 0, bytesRead);

ここに問題があります。ASCIIEncodingは多くのエンコードされた文字を変換せず、それらの文字の代わりに'?' 63を返します。BCD変換ロジックに63を入れると、153が得られます。

このエラーを解決するために、最後の行を変更し、デコードする代わりに、受信したバイトをcharにキャストするだけです。

 foreach (byte b in message)
 {
     data += ((char) b);
 }
4

2 に答える 2

0

これは、いくつかの異なる方法で発生する同様の質問です。

これは、あなたが直面していることの優れた詳細な説明があるサイトです.

それほど難しくはないはずですが、int として処理するのはかなり難しくなります。

Zoned Decimal (BCD) の変換は非常に簡単ですが、メインフレームから ASCII 転送で変換されたファイルを取得する場合は注意が必要です。引き続き変換できますが、FTP 中の ebcdic から ascii への変換により、バイト値が変更されます。

バイナリ ファイルを処理する場合は、はるかに簡単に処理できます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestZoned
{
  class Program
  {
    public static String zoneToString(byte[] zoneBytes)
    {
        Encoding ascii = Encoding.ASCII;
        Encoding ebcdic = Encoding.GetEncoding("IBM037");
        byte[] asciiBytes = null;
        String str = null;

        int zoneLen = zoneBytes.Length;
        int i = zoneLen - 1;
        int b1 = zoneBytes[i];
        b1 = (b1 & 0xf0) >> 4;

        switch (b1)
        {
            case 13:
            case 11:
                zoneBytes[i] = (byte)(zoneBytes[i] | 0xf0);
                asciiBytes = Encoding.Convert(ebcdic, ascii, zoneBytes);

                str = "-" + ASCIIEncoding.ASCII.GetString(asciiBytes);
                break;

            default:
                zoneBytes[i] = (byte)(zoneBytes[i] | 0xf0);
                asciiBytes = Encoding.Convert(ebcdic, ascii, zoneBytes);

                str = ASCIIEncoding.ASCII.GetString(asciiBytes);
                break;
        }

        return (str);
    }

    static void Main(string[] args)
    {
        byte[] array =  { 0xf0, 0xf0, 0xf1 }; // 001
        byte[] pos = { 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; // 123456789
        byte[] neg = { 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xd9 }; // -123456789

        Console.WriteLine("Converted: {0}", zoneToString(array));
        Console.WriteLine("Converted: {0}", zoneToString(pos));
        Console.WriteLine("Converted: {0}", zoneToString(neg));
    }
}

}

于 2012-07-27T14:44:01.797 に答える
0

似たようなものに固執したい場合

    public static String GetStringFromBcd(byte[] zoneBytes)
    {
        StringBuilder buffer = new StringBuilder();

        int b1 = (zoneBytes[zoneBytes.Length - 1] & 0xf0) >> 4;
        if ( (b1 == 13) || (b1 == 11) ) buffer.Append("-");

        for (int i = 0; i < zoneBytes.Length; i++)
        {
            buffer.Append((zoneBytes[i] & 0x0f));
        }

        return buffer.ToString();
    }
于 2012-07-27T15:33:34.807 に答える