代码之家  ›  专栏  ›  技术社区  ›  thotheolh

Java卡中整数的二进制表示到ASCII的转换

  •  3
  • thotheolh  · 技术社区  · 6 年前

    我想把任意长度的整数转换成ASCII格式的二进制格式。

    33023 ,十六进制字节为 0x80ff . 我想代表 0x80ff型 转换为ASCII格式 33023 以十六进制表示 0x3333303233 .

    我正在做一件事 Java卡

    解决这个问题最有效的方法是什么,因为16位智能卡上的Java卡环境非常有限。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Maarten Bodewes    6 年前

    这段代码只是将字节除以新的基数(10表示小数),然后返回余数。剩下的就是下一个 数字。由于输入值现在已被除,下一个余数是比前一个位置更重要的数字。它不断除以并返回余数,直到值为零,计算完成。

    算法中最棘手的部分是内环,内环将值除以10,而剩余部分则使用字节的尾部除法返回。每次运行提供一个余数/小数位数。这也意味着函数的顺序是 O(n) 结果中的位数(将尾部除法定义为单个操作)。请注意 可通过以下公式计算 ceil(bigNumBytes * log_10(256)) :其结果也出现在预先计算的 BCD_SIZE_PER_BYTES 桌子。 log_10(256) 2.408 .

    /**
     * Converts an unsigned big endian value within the buffer to the same value
     * stored using ASCII digits. The ASCII digits may be zero padded, depending
     * on the value within the buffer.
     * <p>
     * <strong>Warning:</strong> this method zeros the value in the buffer that
     * contains the original number. It is strongly recommended that the input
     * value is in fast transient memory as it will be overwritten multiple
     * times - until it is all zero.
     * </p>
     * <p>
     * <strong>Warning:</strong> this method fails if not enough bytes are
     * available in the output BCD buffer while destroying the input buffer.
     * </p>
     * <p>
     * <strong>Warning:</strong> the big endian number can only occupy 16 bytes
     * or less for this implementation.
     * </p>
     * 
     * @param uBigBuf
     *            the buffer containing the unsigned big endian number
     * @param uBigOff
     *            the offset of the unsigned big endian number in the buffer
     * @param uBigLen
     *            the length of the unsigned big endian number in the buffer
     * @param decBuf
     *            the buffer that is to receive the BCD encoded number
     * @param decOff
     *            the offset in the buffer to receive the BCD encoded number
     * @return decLen, the length in the buffer of the received BCD encoded
     *         number
     */
    public static short toDecimalASCII(byte[] uBigBuf, short uBigOff,
            short uBigLen, byte[] decBuf, short decOff) {
    
        // variables required to perform long division by 10 over bytes
        // possible optimization: reuse remainder for dividend (yuk!)
        short dividend, division, remainder;
    
        // calculate stuff outside of loop
        final short uBigEnd = (short) (uBigOff + uBigLen);
        final short decDigits = BYTES_TO_DECIMAL_SIZE[uBigLen];
    
        // --- basically perform division by 10 in a loop, storing the remainder
    
        // traverse from right (least significant) to the left for the decimals
        for (short decIndex = (short) (decOff + decDigits - 1); decIndex >= decOff; decIndex--) {
    
            // --- the following code performs tail division by 10 over bytes
    
            // clear remainder at the start of the division
            remainder = 0;
    
            // traverse from left (most significant) to the right for the input
            for (short uBigIndex = uBigOff; uBigIndex < uBigEnd; uBigIndex++) {
    
                // get rest of previous result times 256 (bytes are base 256)
                // ... and add next positive byte value
                // optimization: doing shift by 8 positions instead of mul.
                dividend = (short) ((remainder << 8) + (uBigBuf[uBigIndex] & 0xFF));
    
                // do the division
                division = (short) (dividend / 10);
    
                // optimization: perform the modular calculation using
                // ... subtraction and multiplication
                // ... instead of calculating the remainder directly
                remainder = (short) (dividend - division * 10);
    
                // store the result in place for the next iteration
                uBigBuf[uBigIndex] = (byte) division;
            }
            // the remainder is what we were after
            // add '0' value to create ASCII digits
            decBuf[decIndex] = (byte) (remainder + '0');
        }
    
        return decDigits;
    }
    
    /*
     * pre-calculated array storing the number of decimal digits for big endian
     * encoded number with len bytes: ceil(len * log_10(256))
     */
    private static final byte[] BYTES_TO_DECIMAL_SIZE = { 0, 3, 5, 8, 10, 13,
            15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39 };
    

    要扩展输入大小,只需计算并在表中存储下一个十进制大小。。。