【问题标题】:Dynamic String Size动态字符串大小
【发布时间】:2014-08-13 08:46:47
【问题描述】:

我正在尝试解码 base64 编码的字符串。 为此,我编写了以下代码:

String bytesEncoded = "rO0ABXNyADZ6YS5jby5zYi5wYXltZW50cy50by5pbnN0cnVjdGlvbi5CYXRjaEZpbGVVcGxvYWRD"
+ "UlVEVE8dnJ9z1jdsQwIAB0wAEGFic29sdXRlUGF0aE5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztM"
+ "AAliYXRjaFR5cGVxAH4AAUwAFmN1c3RvbWVyUGF5bWVudFR5cGVLZXl0ABBMamF2YS9sYW5nL0xv"
+ "bmc7TAAhZW5jb2RlZEJ5dGVTdHJlYW1QYXltZW50QmF0Y2hGaWxlcQB+AAFMAAhmaWxlTmFtZXEA"
+ "fgABTAAIZmlsZVR5cGVxAH4AAUwABmlzc3Vlc3QAJEx6YS9jby9zYi9jb3JlL2NvbW1vbi90by9J"
+ "c3N1ZUxvZ1RPO3hyAB96YS5jby5zYi5jb3JlLnRvLkFic3RyYWN0Q1JVRFRP9ka5cD8D+JUCAAJK"
+ "AA12ZXJzaW9uTnVtYmVyTAAGYWN0aW9ucQB+AAF4cP//////////dAAGdXBsb2FkdACYQzpcbkJv"
+ "bF9Mb2FkVGVzdGluZ1xQZXJmb3JtYW5jZVRlc3RpbmdcbkJPTFxDVkFcUmVsZWFzZTE1XE1pc2Mg"
+ "RG9jc1xGaWxlcyBmb3IgVXBsb2FkXG5Cb2wgUHJvcCBSMTMtIERvbWVzdGljIGFkaG9jIDA4MDgy"
+ "MDE0IFRhbnphbmlhQmVuMiBWYWxpZCBQZXJmMi54bWx0AAdQYXltZW50c3IADmphdmEubGFuZy5M"
+ "b25nO4vkkMyPI98CAAFKAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAA"
+ "AAAAJKWidANsSDRzSUFBQUFBQUFBQU1WVlhXL1RNQlI5UitJL1JIMHZUanNZcmVSbFN0TU5LcUZS"
+ "MnNJUWIzZk9YV3Nwc1lmamxKVmZqeE5ucVowR05DUWtwS3J4T2ZmNmZweHJKL1R5TWMrQ1BhcUNT"
+ "M0V4R0wwS0J3RUtKbE11dGhlRHo1dnI0V1FRRkJwRUNwa1VlREVRY25BWnZYeEJaNkRaTHFKSldX"
+ "aVpvNnJoQ3UrakZXWUlCUVliRUQ5QmNBakNTVGdaaDZQWHdSTFZmVENtNUdRTFhZaENxNUpwVThJ"
+ "eG9rTldUZzRjaG1FNE9zYnBPTklPTnM0bS9URDVGdHR0WGZjVmZpKzV3dlRxRVZsWnNYUFFHRlVW"
+ "RDhPSitWSFM3MEdYU2pJc0NpUFV4d2RiK2tQTDNFQ08wUnJWbmpQOGdIdk1LT2tZSGVjdmtKVVkz"
+ "VWlWZytkbmVVcE9FeVU3VUZzc1pnZ0tWYlIrSHhzMVBJcHVGSWdDT3BJNlpLT01JMlBINkViWUhC"
+ "NHdtbFBTcFdnaVM2RlJMVUhwUTcySm5EQlhqMndIWW91cldqUGl3eWVVU0tHVkNXeGo5TEtmU3Fu"
+ "aEtEN3A0QmE2cG9qR2pGVUZtVzdxZW9sOTJBRVErMGptaTVzeXY2dEVJODY2MmRuQWFYaHUxQXFu"
+ "MC9Fb1BLZkVOOUxGSFZSNW0wZWI4K21rWVJybk5lT2N2cGF6T3QralNrcWx6TTA3UkxQYlpTTzF5"
+ "M3JxUDMrK3c3OGJjdktNSVF1K1JjV2haOVpMT09Rb3pMeWdxQWZSd2Y5MkdLT3o2ZmpOMlg4YWh0"
+ "dTZpWjFXQ2RPbWw3a1J1dENjeGVsT3NxZkdsdEs4UkxNNFRaVzV5YVlodS9qQVJkVzdoOVphSWVw"
+ "R0ZSZllFSWxNNjNlQ0F6YnloMmo4ajh1NlFuVllsM2R6dnVlRnZSbDlaTU1kclczMHRscml0eHR2"
+ "c2RMcW1nc1FqRU5XeWNoMWFjK2lOODVqaEhiVkpHbmE4TkJza1VScjh6ZTdmZmVWa2dyUm1WR2U3"
+ "ZFpTNmRyRkRQN3MvSzJ4K1RRbC9iV1FwdEpGVlh5T0tRZDErR1B4ZFU2YjJldWpvMGV2NENlaS9h"
+ "YW1ubUw4cTAyOHp5R3hIOXBmc2pQKzlLZ0hBQUE9dABDbkJvbCBQcm9wIFIxMy0gRG9tZXN0aWMg"
+ "YWRob2MgMDgwODIwMTQgVGFuemFuaWFCZW4yIFZhbGlkIFBlcmYyLnhtbHBw";

byte[] decodedBytes = Base64.decodeBase64(bytesEncoded);
System.out.println("decodedBytes " + new String(decodedBytes));

我得到的输出如下所示:

System.out: decodedBytes ’

现在我的问题是,我想知道这是否是由于长度可变。如果是,有没有办法增加长度?

我是 java 新手,通过互联网搜索做到了这一点。如果我很幼稚,请忽略。

我试图只转换编码字符串的一部分(只是最后一行。如下所示),它正确地向我显示了字符串。

String bytesEncoded = "YWRob2MgMDgwODIwMTQgVGFuemFuaWFCZW4yIFZhbGlkIFBlcmYyLnhtbHBw";

byte[] decodedBytes = Base64.decodeBase64(bytesEncoded);
System.out.println("decodedBytes " + new String(decodedBytes));

以下相同的输出:

System.out: decodedBytes adhoc 08082014 TanzaniaBen2 Valid Perf2.xmlpp

【问题讨论】:

  • 原文是什么?
  • 原文是第一个输入的。那就是要解码
  • 如果我通过在线 base64-encoder/decoder 使用您的 base64 字符串,您似乎正在尝试填充 za.co.sb.payments.to.instruction.BatchFileUploadCRUDTO 类的序列化对象的字节到一个字符串
  • 没错。但我没有得到完整的字符串
  • 我刚刚将您的代码 sn-p 复制并粘贴到一个新的 Eclipse 项目中,并使用了 Apaches common-codecs 1.9 Base64 类并获得了与在线 base64-encoder/decoder 一样的完整预期输出

标签: java string base64 decode maxstringcontentlength


【解决方案1】:

解码后的字节根本不表示默认字符编码中的字符串(可能因平台而异)。

它甚至可能根本不表示字符串(在您的情况下似乎很可能)。但如果是这样,您应该始终像这样明确指定编码:

String s = new String(bytesDecoded, charsetName);
// or
String s = new String(bytesDecoded, charset);

String 的构造函数可以取任意长度的字节数组,这不是问题。

这是一个字符集很重要的例子:

String s = "Hi éáű!";
Systme.out.println(s); // Prints "Hi éáű!" obviously

byte[] b = s.getBytes(StandardCharsets.UTF_8);

// Next line also prints "Hi éáű!", charsets match:
System.out.println(new String(b, StandardCharsets.UTF_8));

// Next line prints "Hi éáű!", decoded with a different charset!
System.out.println(new String(b, StandardCharsets.ISO_8859_1));

另请注意,String 构造函数不会解释 BOM 序列(例如,如果您解码的字节数组以字节顺序标记序列开头,它将不会被正确处理,而是被解释为字符串的字节)。

【讨论】:

    【解决方案2】:

    您尝试转换的字节块绝对不是文本字符串,而是某种二进制数据。

    它包含多个 0 值字节,通常表示一个字符串终止符,这就是为什么您的原始代码只显示两个字符的原因。

    【讨论】:

    • Java 不使用 C 风格('\0' 字符终止)字符串或字节序列。
    • 我认为这可能是一个原因。但后来我尝试将整个序列放在一行中。它仍然显示相同的内容。
    • Java 作为一种语言不使用字符串终止符,但是当您在大多数控制台查看器上输出时,带有 '\0' 的字符串会被剪切。
    【解决方案3】:

    使用 apache commons 编解码器。它有一个Base64 类。

    像这样使用它:

    import org.apache.commons.codec.binary.Base64;
    [..]
    byte[] decoded = Base64.decodeBase64(base64string);
    

    Maven 工件:

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.9</version>
    </dependency>
    

    【讨论】:

    • 根据其他答案,直接解码为字节数组。您可以检查它是否包含有用的文本信息。
    • 那么就是二进制数据。如果您确定不是,您仍然可以尝试通过以下方式对其进行强制编码:Commons Codec StringUtils
    【解决方案4】:

    由于解码后的字节实际上包含一个二进制文件(带有小文本部分),您可能并不打算将解码后的字节视为编码的文本字符,这正是String(byte[]) 将为您做的事情。

    相反,您可能只想打印可打印的字符(通过逐个字符打印出字节,并测试每个字符以查看它是否可显示),如this topic 中所述,或者将其显示为字符串十六进制字符,如this topic中所述

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-13
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2022-12-24
      相关资源
      最近更新 更多