You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASCII字符数组与long类型互转在值128处失败的问题解决

ASCII字符数组与long类型互转的问题解决

问题背景

我实现了将ASCII字符数组转换为long类型、以及long类型转换为ASCII字符数组的Java方法,但在处理值128时转换失败。

错误实现代码

最初的转换方法依赖字符编码/解码实现:

public long asciiToLong(char[] in) {
    CharBuffer charBuffer = CharBuffer.wrap(in);
    ByteBuffer byteBuffer = StandardCharsets.US_ASCII.encode(charBuffer);
    
    byte[] byteArray = new byte[byteBuffer.remaining()];
    byteBuffer.get(byteArray);

    long result = ByteBuffer.wrap(new String(byteArray).getBytes()).getLong();
    return result;
}

public char[] longToAscii(long in) {
    ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
    buffer.putLong(in);
    byte[] b =  buffer.array();
    CharBuffer charBuffer = StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(b));

    char[] result = new char[charBuffer.remaining()];
    charBuffer.get(result);
    
    return result;
}

测试代码及失败结果

使用以下循环测试时,在值128处出现转换错误:

for (long l = 0 ; l < 100000 ; l++) {
    char[] ascii = longToAscii(l);
    System.out.printf("%d -> ", l);
    long l2 = asciiToLong(ascii);
    System.err.printf("%d\n", l2);
    if (l != l2) {
        throw new RuntimeException();
    }
}

输出结果(部分):

0 -> 0
1 -> 1
2 -> 2
3 -> 3
// 中间输出省略..
126 -> 126
127 -> 127
128 -> 63 // 转换失败

更换解码用的StandardCharset后,仍在同一位置失败,仅错误结果值不同。

问题原因

US_ASCII字符集仅支持0-127的字符范围,当处理值为128的字节(超出ASCII范围)时,编码/解码过程会自动将其替换为替换字符63(即'?'),导致原始数值信息丢失。本质上,这里误用了字符编码转换来处理原始字节数据——需求是直接将字节与char做数值映射,而非进行字符编码的编解码。

正确实现(无编码方式)

最终通过直接处理字节与char的数值映射实现了正确转换,代码如下:

public long asciiToLong(char[] in) {
    long result = byteArrayToLong(charArrayToByteArray(in));
    return result;
}

public char[] longToAscii(long in) {
    byte[] bs = longToByteArray(in);
    char[] result = new char[bs.length];
    int i = bs.length;
    for (byte b : bs) {
        i--;
        result[i] = (char) b;
    }
    return result;
}

private long byteArrayToLong(byte[] b) {
    long result = 0;
    for (byte value : b) {
        result <<= Byte.SIZE;
        result |= (value & 0xFF);
    }
    return result;
}

private byte[] charArrayToByteArray(char[] charArray) {
    byte[] byteArray = new byte[charArray.length];
    for (int i = 0 ; i < charArray.length ; i++) {
        byteArray[i] = (byte) (0xFF & (int) charArray[i]);
    }
    return byteArray;
}

private byte[] longToByteArray(long v) {
    byte[] b = new byte[Long.BYTES];
    int i = 0;
    int[] j = { 0, 8, 16, 24, 32, 40, 48, 56 };
    while (i < Long.BYTES) {
        b[i] = (byte)(v >>> j[i]);
        i++;
    }
    return b;
}

验证测试及结果

使用以下测试代码验证:

long l;
long l2;
for (l = 0 ; l < 100000 ; l++) {
    char[] ascii = longToAscii(l);
    System.out.printf("%d->", l);
    l2 = asciiToLong(ascii);
    System.out.printf("%d\n", l2);
    if (l != l2) {
        throw new RuntimeException();
    }
}

测试输出无错误(部分):

0 -> 0
1 -> 1
2 -> 2
3 -> 3
// 中间输出省略..
99999 -> 99999

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:25:54