C#转换COMP-3压缩十进制到人类可读的价值(C#: Convert COMP-3 Packed

2019-07-18 03:41发布

我有一个C#应用程序来处理一系列从大型机进来的ASCII纯文本文件。 一个新的进料已被引入用压缩十进制(COMP-3)字段,其需要被转换为数字值。

该文件正在通过FTP传输,使用ASCII传输模式。 我担心的二进制字段可能包含的内容将被解释为非常低的ASCII码或控制字符,而不是一个值 - 或者更糟,可能会丢失在FTP过程。

更重要的是,该领域正在读取为字符串。 我可以灵活地解决这部分(即某种流),但业务会给我推回。

要求改为“从十六进制ASCII码转换”,但显然这并不会产生正确的值。 任何帮助,将不胜感激; 它不需要,只要你能解释一下转换过程的逻辑是特定语言。

Answer 1:

首先,你必须消除的,将由ASCII传输模式造成的线(EOL)翻译问题结束。 你是绝对正确予以关注数据损坏时的BCD值正好对应于EOL字符。 这个问题的最严重的方面是,它很少会和意外发生。

最好的解决办法是改变传输模式为BIN。 这是合适的,因为你在传输数据是二进制的。 如果不能使用正确的FTP传输模式,您可以撤消在代码ASCII模式损害。 所有你需要做的就是转换\ r \ n对回\ n。 如果我是你,我会确保这是行之有效的。

一旦你处理了EOL问题,COMP-3的转换是相当straigtforward。 我能找到这篇文章在MS知识库与BASIC示例代码。 请参阅下面这段代码的VB.NET端口。

既然你要处理的COMP-3的值,你正在阅读几乎可以肯定的文件格式已经固定记录大小固定字段长度。 如果我是你,你去任何进一步与此之前,我会得到我的文件格式规范的手中。 你应该使用BinaryReader在这个数据的工作。 如果有人推回在这一点上,我会走开。 让他们找别人放纵自己的愚蠢。

这里是基本的示例代码的VB.NET端口。 我没有测试过这一点,因为我没有访问COMP-3文件。 如果这也不行,我要提到回原来的MS的示例代码进行指导,或者在其他的答案对这个问题的引用。

Imports Microsoft.VisualBasic

Module Module1

'Sample COMP-3 conversion code
'Adapted from http://support.microsoft.com/kb/65323
'This code has not been tested

Sub Main()

    Dim Digits%(15)       'Holds the digits for each number (max = 16).
    Dim Basiceqv#(1000)   'Holds the Basic equivalent of each COMP-3 number.

    'Added to make code compile
    Dim MyByte As Char, HighPower%, HighNibble%
    Dim LowNibble%, Digit%, E%, Decimal%, FileName$


    'Clear the screen, get the filename and the amount of decimal places
    'desired for each number, and open the file for sequential input:
    FileName$ = InputBox("Enter the COBOL data file name: ")
    Decimal% = InputBox("Enter the number of decimal places desired: ")

    FileOpen(1, FileName$, OpenMode.Binary)

    Do Until EOF(1)   'Loop until the end of the file is reached.
        Input(1, MyByte)
        If MyByte = Chr(0) Then     'Check if byte is 0 (ASC won't work on 0).
            Digits%(HighPower%) = 0       'Make next two digits 0. Increment
            Digits%(HighPower% + 1) = 0   'the high power to reflect the
            HighPower% = HighPower% + 2   'number of digits in the number
            'plus 1.
        Else
            HighNibble% = Asc(MyByte) \ 16      'Extract the high and low
            LowNibble% = Asc(MyByte) And &HF    'nibbles from the byte. The
            Digits%(HighPower%) = HighNibble%  'high nibble will always be a
            'digit.
            If LowNibble% <= 9 Then                   'If low nibble is a
                'digit, assign it and
                Digits%(HighPower% + 1) = LowNibble%   'increment the high
                HighPower% = HighPower% + 2            'power accordingly.
            Else
                HighPower% = HighPower% + 1 'Low nibble was not a digit but a
                Digit% = 0                  '+ or - signals end of number.

                'Start at the highest power of 10 for the number and multiply
                'each digit by the power of 10 place it occupies.
                For Power% = (HighPower% - 1) To 0 Step -1
                    Basiceqv#(E%) = Basiceqv#(E%) + (Digits%(Digit%) * (10 ^ Power%))
                    Digit% = Digit% + 1
                Next

                'If the sign read was negative, make the number negative.
                If LowNibble% = 13 Then
                    Basiceqv#(E%) = Basiceqv#(E%) - (2 * Basiceqv#(E%))
                End If

                'Give the number the desired amount of decimal places, print
                'the number, increment E% to point to the next number to be
                'converted, and reinitialize the highest power.
                Basiceqv#(E%) = Basiceqv#(E%) / (10 ^ Decimal%)
                Print(Basiceqv#(E%))
                E% = E% + 1
                HighPower% = 0
            End If
        End If
    Loop

    FileClose()   'Close the COBOL data file, and end.
End Sub

End Module


Answer 2:

我一直在看关于转换在许多板上的帖子比较-3从“传统”的主机文件的东西在C#中可用的BCD数据。 首先,我想说我是小于,其中一些职位已经收到的答复迷恋 - 已基本上说,尤其是那些“为什么难为我们这些非C#/ C ++相关的职位”,也是“如果您需要了解某种COBOL约定的答案,你为什么不就往COBOL为本网站”。 这对我来说,是有将是一个需要大概许多年里,(可惜),为软件开发者了解如何处理一些存在在现实世界中,这些历史遗留问题,完成学士学位。 所以,即使我得到抨击对这个职位以下的代码,我将与大家分享一个现实世界的经验,我不得不处理有关COMP-3 / EBCDIC转换(是的,我是他的“谁说话软盘,纸带,光盘包等... - 我一直自1979" 年以来)的软件工程师。

首先 - 明白,你从传统主框架系统,如IBM读取任意文件要将数据呈现给您EBCDIC格式和以任何的数据转换成C#/ C ++字符串就可以对付你将不得不使用正确的代码页转换到数据进入ASCII格式。 如何处理这方面的一个很好的例子是:

StreamReader的READFILE =新的StreamReader(路径,Encoding.GetEncoding(037); // 037 = EBCDIC为ASCII翻译。

这将确保任何东西,你从这个流中读取将被转换为ASCII,并且可以在一个字符串格式使用。 这包括“区位十进制”(PIC 9)和“文本”(PIC X)由COBOL声明的字段。 然而,这并不一定时读入一个char []或byte []数组转换COMP-3字段到正确的“二进制” equivelant。 要做到这一点,那你永远会得到这个翻译正确的唯一途径(即使使用UTF-8,UTF-16,默认或其他)的代码页,你将要打开的文件是这样的:

的FileStream FILESTREAM =新的FileStream(路径,FIleMode.Open,FIleAccess.Read,FileShare.Read);

当然,“FileShare.Read”选项是“可选”。

当你隔离,你要转换为十进制值(并随后到如果需要的话ASCII字符串),你可以使用下面的代码领域 - 这已经基本从微软“UnpackDecimal”偷发布你可以得到在:

http://www.microsoft.com/downloads/details.aspx?familyid=0e4bba52-cc52-4d89-8590-cda297ff7fbd&displaylang=en

我已经分离(我认为)是什么这个逻辑的最重要组成部分和巩固它分成两,你可以用你想要的东西做的方法。 对于我而言,我选择了离开这为返回一个十进制值,然后我可以有我想要做的。 基本上,该方法被称为“解包”和传递给它一个byte []数组(不超过12个字节)和标度作为int,这是要在十进制值又回到小数的数。 我希望这对你的作品,以及它为我做的。

    private Decimal Unpack(byte[] inp, int scale)
    {
        long lo = 0;
        long mid = 0;
        long hi = 0;
        bool isNegative;

        // this nybble stores only the sign, not a digit.  
        // "C" hex is positive, "D" hex is negative, and "F" hex is unsigned. 
        switch (nibble(inp, 0))
        {
            case 0x0D:
                isNegative = true;
                break;
            case 0x0F:
            case 0x0C:
                isNegative = false;
                break;
            default:
                throw new Exception("Bad sign nibble");
        }
        long intermediate;
        long carry;
        long digit;
        for (int j = inp.Length * 2 - 1; j > 0; j--)
        {
            // multiply by 10
            intermediate = lo * 10;
            lo = intermediate & 0xffffffff;
            carry = intermediate >> 32;
            intermediate = mid * 10 + carry;
            mid = intermediate & 0xffffffff;
            carry = intermediate >> 32;
            intermediate = hi * 10 + carry;
            hi = intermediate & 0xffffffff;
            carry = intermediate >> 32;
            // By limiting input length to 14, we ensure overflow will never occur

            digit = nibble(inp, j);
            if (digit > 9)
            {
                throw new Exception("Bad digit");
            }
            intermediate = lo + digit;
            lo = intermediate & 0xffffffff;
            carry = intermediate >> 32;
            if (carry > 0)
            {
                intermediate = mid + carry;
                mid = intermediate & 0xffffffff;
                carry = intermediate >> 32;
                if (carry > 0)
                {
                    intermediate = hi + carry;
                    hi = intermediate & 0xffffffff;
                    carry = intermediate >> 32;
                    // carry should never be non-zero. Back up with validation
                }
            }
        }
        return new Decimal((int)lo, (int)mid, (int)hi, isNegative, (byte)scale);
    }

    private int nibble(byte[] inp, int nibbleNo)
    {
        int b = inp[inp.Length - 1 - nibbleNo / 2];
        return (nibbleNo % 2 == 0) ? (b & 0x0000000F) : (b >> 4);
    }

如果您有任何问题,张贴在这里 - 因为我怀疑我会得到“火烧”和其他人一样谁选择了张贴有相关的问题,今天的问题...

谢谢,约翰 - 上古。



Answer 3:

如果原始数据是在EBCDIC您的COMP-3场已出现乱码。 该FTP进程已经做了EBCDIC在COMP-3场是不是你想要的字节值的ASCII翻译。 要纠正这一点,你可以:

1),所以你得到的原始EBCDIC数据使用二进制模式转移。 然后你的COMP-3场转换为数字和翻译上的记录,以ASCII任何其他EBCDIC文本。 外带字段存储与下半部字节作为一个标志半字节每个数字(F为正和其他值,通常是d或E,是负的)。 在PIC 999.99 USAGE COMP-3。将X'01234F存储123.4“(三个字节)和-123中相同的字段是X'01230D”。

2)具有发送器转换字段为用法是显示标志是世界领先的(或结尾)数值字段。 此存储为EBCDIC位数字与符号作为一个单独的负字符串数( - )或空白字符。 所有的数字和符号正确转换到其对应的ASCII码的FTP传输。



Answer 4:

我很抱歉,如果我在这里是大错特错,但也许此代码示例,我会粘贴在这里可以帮助你。 这来自VBRocks ...

Imports System
Imports System.IO
Imports System.Text
Imports System.Text.Encoding



'4/20/07 submission includes a line spacing addition when a control character is used:
'   The line spacing is calculated off of the 3rd control character.
'
'   Also includes the 4/18 modification of determining end of file.

'4/26/07 submission inclues an addition of 6 to the record length when the 4th control
'   character is an 8.  This is because these records were being truncated.


'Authored by Gary A. Lima, aka. VBRocks



''' <summary>
''' Translates an EBCDIC file to an ASCII file.
''' </summary>
''' <remarks></remarks>
Public Class EBCDIC_to_ASCII_Translator

#Region " Example"

    Private Sub Example()
        'Set your source file and destination file paths
        Dim sSourcePath As String = "c:\Temp\MyEBCDICFile"
        Dim sDestinationPath As String = "c:\Temp\TranslatedFile.txt"

        Dim trans As New EBCDIC_to_ASCII_Translator()

        'If your EBCDIC file uses Control records to determine the length of a record, then this to True
        trans.UseControlRecord = True

        'If the first record of your EBCDIC file is filler (junk), then set this to True
        trans.IgnoreFirstRecord = True

        'EBCDIC files are written in block lengths, set your block length (Example:  134, 900, Etc.)
        trans.BlockLength = 900

        'This method will actually translate your source file and output it to the specified destination file path
        trans.TranslateFile(sSourcePath, sDestinationPath)


        'Here is a alternate example:
        'No Control record is used
        'trans.UseControlRecord = False

        'Translate the whole file, including the first record
        'trans.IgnoreFirstRecord = False

        'Set the block length
        'trans.BlockLength = 134

        'Translate...
        'trans.TranslateFile(sSourcePath, sDestinationPath)



        '*** Some additional methods that you can use are:

        'Trim off leading characters from left side of string (position 0 to...)
        'trans.LTrim = 15

        'Translate 1 EBCDIC character to an ASCII character
        'Dim strASCIIChar as String = trans.TranslateCharacter("S")

        'Translate an EBCDIC character array to an ASCII string
        'trans.TranslateCharacters(chrEBCDICArray)

        'Translates an EBCDIC string to an ASCII string
        'Dim strASCII As String = trans.TranslateString("EBCDIC String")


    End Sub

#End Region    'Example

    'Translate characters from EBCDIC to ASCII

    Private ASCIIEncoding As Encoding = Encoding.ASCII
    Private EBCDICEncoding As Encoding = Encoding.GetEncoding(37)  'EBCDIC

    'Block Length:  Can be fixed (Ex:  134). 
    Private miBlockLength As Integer = 0
    Private mbUseControlRec As Boolean = True        'If set to False, will return exact block length
    Private mbIgnoreFirstRecord As Boolean = True    'Will Ignore first record if set to true  (First record may be filler)
    Private miLTrim As Integer = 0

    ''' <summary>
    ''' Translates SourceFile from EBCDIC to ASCII.  Writes output to file path specified by DestinationFile parameter.
    ''' Set the BlockLength Property to designate block size to read.
    ''' </summary>
    ''' <param name="SourceFile">Enter the path of the Source File.</param>
    ''' <param name="DestinationFile">Enter the path of the Destination File.</param>
    ''' <remarks></remarks>
    Public Sub TranslateFile(ByVal SourceFile As String, ByVal DestinationFile As String)

        Dim iRecordLength As Integer     'Stores length of a record, not including the length of the Control Record (if used)
        Dim sRecord As String = ""         'Stores the actual record
        Dim iLineSpace As Integer = 1    'LineSpace:  1 for Single Space, 2 for Double Space, 3 for Triple Space...

        Dim iControlPosSix As Byte()      'Stores the 6th character of a Control Record (used to calculate record length)
        Dim iControlRec As Byte()          'Stores the EBCDIC Control Record (First 6 characters of record)
        Dim bEOR As Boolean                'End of Record Flag
        Dim bBOF As Boolean = True      'Beginning of file
        Dim iConsumedChars As Integer = 0     'Stores the number of consumed characters in the current block
        Dim bIgnoreRecord As Boolean = mbIgnoreFirstRecord   'Ignores the first record if set.

        Dim ControlArray(5) As Char         'Stores Control Record (first 6 bytes)
        Dim chrArray As Char()              'Stores characters just after read from file

        Dim sr As New StreamReader(SourceFile, EBCDICEncoding)
        Dim sw As New StreamWriter(DestinationFile)

        'Set the RecordLength to the RecordLength Property (below)
        iRecordLength = miBlockLength

        'Loop through entire file
        Do Until sr.EndOfStream = True

            'If using a Control Record, then check record for valid data.
            If mbUseControlRec = True Then
                'Read the Control Record (first 6 characters of the record)
                sr.ReadBlock(ControlArray, 0, 6)

                'Update the value of consumed (read) characters
                iConsumedChars += ControlArray.Length

                'Get the bytes of the Control Record Array
                iControlRec = EBCDICEncoding.GetBytes(ControlArray)

                'Set the line spacing  (position 3 divided by 64)
                '   (64 decimal = Single Spacing; 128 decimal = Double Spacing)
                iLineSpace = iControlRec(2) / 64


                'Check the Control record for End of File
                'If the Control record has a 8 or 10 in position 1, and a 1 in postion 2, then it is the end of the file
                If (iControlRec(0) = 8 OrElse iControlRec(0) = 10) AndAlso _
                    iControlRec(1) = 1 Then

                    If bBOF = False Then
                        Exit Do

                    Else
                        'The Beginning of file flag is set to true by default, so when the first
                        '   record is encountered, it is bypassed and the bBOF flag is set to False
                        bBOF = False

                    End If    'If bBOF = Fals

                End If    'If (iControlRec(0) = 8 OrElse



                'Set the default value for the End of Record flag to True
                '   If the Control Record has all zeros, then it's True, else False
                bEOR = True

                'If the Control record contains all zeros, bEOR will stay True, else it will be set to False
                For i As Integer = 0 To 5
                    If iControlRec(i) > 0 Then
                        bEOR = False

                        Exit For

                    End If    'If iControlRec(i) > 0

                Next    'For i As Integer = 0 To 5

                If bEOR = False Then
                    'Convert EBCDIC character to ASCII
                    'Multiply the 6th byte by 6 to get record length
                    '   Why multiply by 6?  Because it works.
                    iControlPosSix = EBCDICEncoding.GetBytes(ControlArray(5))

                    'If the 4th position of the control record is an 8, then add 6
                    '    to the record length to pick up remaining characters.
                    If iControlRec(3) = 8 Then
                        iRecordLength = CInt(iControlPosSix(0)) * 6 + 6

                    Else
                        iRecordLength = CInt(iControlPosSix(0)) * 6

                    End If

                    'Add the length of the record to the Consumed Characters counter
                    iConsumedChars += iRecordLength

                Else
                    'If the Control Record had all zeros in it, then it is the end of the Block.

                    'Consume the remainder of the block so we can continue at the beginning of the next block.
                    ReDim chrArray(miBlockLength - iConsumedChars - 1)
                    'ReDim chrArray(iRecordLength - iConsumedChars - 1)

                    'Consume (read) the remaining characters in the block.  
                    '   We are not doing anything with them because they are not actual records.
                    'sr.ReadBlock(chrArray, 0, iRecordLength - iConsumedChars)
                    sr.ReadBlock(chrArray, 0, miBlockLength - iConsumedChars)

                    'Reset the Consumed Characters counter
                    iConsumedChars = 0

                    'Set the Record Length to 0 so it will not be processed below.
                    iRecordLength = 0

                End If    ' If bEOR = False

            End If    'If mbUseControlRec = True



            If iRecordLength > 0 Then
                'Resize our array, dumping previous data.  Because Arrays are Zero (0) based, subtract 1 from the Record length.
                ReDim chrArray(iRecordLength - 1)

                'Read the specfied record length, without the Control Record, because we already consumed (read) it.
                sr.ReadBlock(chrArray, 0, iRecordLength)

                'Copy Character Array to String Array, Converting in the process, then Join the Array to a string
                sRecord = Join(Array.ConvertAll(chrArray, New Converter(Of Char, String)(AddressOf ChrToStr)), "")

                'If the record length was 0, then the Join method may return Nothing
                If IsNothing(sRecord) = False Then

                    If bIgnoreRecord = True Then
                        'Do nothing - bypass record

                        'Reset flag
                        bIgnoreRecord = False

                    Else
                        'Write the line out, LTrimming the specified number of characters.
                        If sRecord.Length >= miLTrim Then
                            sw.WriteLine(sRecord.Remove(0, miLTrim))

                        Else
                            sw.WriteLine(sRecord.Remove(0, sRecord.Length))

                        End If    ' If sRecord.Length >= miLTrim

                        'Write out the number of blank lines specified by the 3rd control character.
                        For i As Integer = 1 To iLineSpace - 1
                            sw.WriteLine("")

                        Next    'For i As Integer = 1 To iLineSpace

                    End If    'If bIgnoreRecord = True


                    'Obviously, if we have read more characters from the file than the designated size of the block,
                    '   then subtract the number of characters we have read into the next block from the block size.
                    If iConsumedChars > miBlockLength Then
                        'If iConsumedChars > iRecordLength Then
                        iConsumedChars = iConsumedChars - miBlockLength
                        'iConsumedChars = iConsumedChars - iRecordLength

                    End If

                End If    'If IsNothing(sRecord) = False

            End If    'If iRecordLength > 0

            'Allow computer to process  (works in a class module, not in a dll)
            'Application.DoEvents()

        Loop

        'Destroy StreamReader (sr)
        sr.Close()
        sr.Dispose()

        'Destroy StreamWriter (sw)
        sw.Close()
        sw.Dispose()

    End Sub



    ''' <summary>
    ''' Translates 1 EBCDIC Character (Char) to an ASCII String
    ''' </summary>
    ''' <param name="chr"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ChrToStr(ByVal chr As Char) As String
        Dim sReturn As String = ""

        'Convert character into byte
        Dim EBCDICbyte As Byte() = EBCDICEncoding.GetBytes(chr)

        'Convert EBCDIC byte to ASCII byte
        Dim ASCIIByte As Byte() = Encoding.Convert(EBCDICEncoding, ASCIIEncoding, EBCDICbyte)

        sReturn = Encoding.ASCII.GetString(ASCIIByte)

        Return sReturn

    End Function



    ''' <summary>
    ''' Translates an EBCDIC String to an ASCII String
    ''' </summary>
    ''' <param name="sStringToTranslate"></param>
    ''' <returns>String</returns>
    ''' <remarks></remarks>
    Public Function TranslateString(ByVal sStringToTranslate As String) As String
        Dim i As Integer = 0
        Dim sReturn As New System.Text.StringBuilder()

        'Loop through the string and translate each character
        For i = 0 To sStringToTranslate.Length - 1
            sReturn.Append(ChrToStr(sStringToTranslate.Substring(i, 1)))

        Next

        Return sReturn.ToString()


    End Function



    ''' <summary>
    ''' Translates 1 EBCDIC Character (Char) to an ASCII String
    ''' </summary>
    ''' <param name="sCharacterToTranslate"></param>
    ''' <returns>String</returns>
    ''' <remarks></remarks>
    Public Function TranslateCharacter(ByVal sCharacterToTranslate As Char) As String

        Return ChrToStr(sCharacterToTranslate)

    End Function



    ''' <summary>
    ''' Translates an EBCDIC Character (Char) Array to an ASCII String
    ''' </summary>
    ''' <param name="sCharacterArrayToTranslate"></param>
    ''' <returns>String</returns>
    ''' <remarks>Remarks</remarks>
    Public Function TranslateCharacters(ByVal sCharacterArrayToTranslate As Char()) As String
        Dim sReturn As String = ""

        'Copy Character Array to String Array, Converting in the process, then Join the Array to a string
        sReturn = Join(Array.ConvertAll(sCharacterArrayToTranslate, _
                            New Converter(Of Char, String)(AddressOf ChrToStr)), "")

        Return sReturn

    End Function


    ''' <summary>
    ''' Block Length must be set.  You can set the BlockLength for specific block sizes (Ex:  134).
    ''' Set UseControlRecord = False for files with specific block sizes (Default is True)
    ''' </summary>
    ''' <value>0</value>
    ''' <returns>Integer</returns>
    ''' <remarks></remarks>
    Public Property BlockLength() As Integer
        Get
            Return miBlockLength

        End Get
        Set(ByVal value As Integer)
            miBlockLength = value

        End Set
    End Property



    ''' <summary>
    ''' Determines whether a ControlKey is used to calculate RecordLength of valid data
    ''' </summary>
    ''' <value>Default value is True</value>
    ''' <returns>Boolean</returns>
    ''' <remarks></remarks>
    Public Property UseControlRecord() As Boolean
        Get
            Return mbUseControlRec

        End Get
        Set(ByVal value As Boolean)
            mbUseControlRec = value

        End Set
    End Property



    ''' <summary>
    ''' Ignores first record if set (Default is True)
    ''' </summary>
    ''' <value>Default is True</value>
    ''' <returns>Boolean</returns>
    ''' <remarks></remarks>
    Public Property IgnoreFirstRecord() As Boolean
        Get
            Return mbIgnoreFirstRecord

        End Get

        Set(ByVal value As Boolean)
            mbIgnoreFirstRecord = value

        End Set
    End Property



    ''' <summary>
    ''' Trims the left side of every string the specfied number of characters.  Default is 0.
    ''' </summary>
    ''' <value>Default is 0.</value>
    ''' <returns>Integer</returns>
    ''' <remarks></remarks>
    Public Property LTrim() As Integer
        Get
            Return miLTrim

        End Get

        Set(ByVal value As Integer)
            miLTrim = value

        End Set
    End Property


End Class


Answer 5:

对于EBCDIC翻译一些有用的链接:

转换表-有用做检查一些值在压缩十进制字段: http://www.simotime.com/asc2ebc1.htm

在MSDN代码页列表:
http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx

和一段代码转换C#中的字节数组字段:

// 500 is the code page for IBM EBCDIC International 
System.Text.Encoding enc = new System.Text.Encoding(500);
string value = enc.GetString(byteArrayField);


Answer 6:

打包的字段在EBCDIC或ASCII相同。 不要运行EBCDIC对他们的ASCII转换。 在净将它们放到一个byte []。

您可以使用按位口罩,并转移到包/解压。 - 但是,这样你就需要通过一些跳铁圈按位老年退休金计划只适用于整数类型的.Net!

一个好的COBOL或C艺术家可以为您指出正确的方向。

找老的球员之一,并且支付了会费(约三瓶啤酒应该这样做)。



文章来源: C#: Convert COMP-3 Packed Decimal to Human-Readable Value