【问题标题】:NumberFormatException on valid number String有效数字字符串上的 NumberFormatException
【发布时间】:2012-07-07 03:38:39
【问题描述】:

我已经看到了一些关于此的其他问题,但错误与字符串中的前导 0 有关。不幸的是,这不是我的情况。

我从外部源接收 base64 格式的加密数据,然后对其进行解码(使用包含的 Base64 库,因为 android sdk 版本为 7),解密消息,毕竟我有一个简单的字符串数字格式。

当我尝试将其转换为 LongInteger 时,我收到此错误:

java.lang.NumberFormatException: Invalid long: "2551122"
    at java.lang.Long.invalidLong(Long.java:125)
    at java.lang.Long.parse(Long.java:362)
    at java.lang.Long.parseLong(Long.java:353)
    at java.lang.Long.parseLong(Long.java:319)
    at com.nzn.lol.LoginActivity$LoginTask.doInBackground(LoginActivity.java:98)
    at com.nzn.lol.LoginActivity$LoginTask.doInBackground(LoginActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:264)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)

检查输入我使用打印,它确实是字符串“2551122”。 当我尝试检查是否相等时,它也不正确

"2551122".equals(numberAsString) // Gives me false

我认为这是一个编码问题,并尝试获取解码的字节并以几种编码创建字符串,还尝试使用这些相同的几种编码从 base64 字符串中解码字节,但仍然不知道是什么导致了这个错误。

感谢您的帮助

更新

这是解密字符串的代码(Encryptor 类):

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance(encryptionAlgorithim);
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iVector));
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

public String decrypt(String encryptedString, String key) {

    byte[] keyBytes = key.getBytes();
    byte[] decoded = Base64.decode(encryptedString); // Decodes the string from base64 to byte[]
    byte[] result = decrypt(keyBytes, decoded);
    return new String(result);
}

这是引发错误的方式:

Encryptor encryptor = new Encryptor();
Long.parseLong(encryptor.decrypt(base64String, secretKey)) // Throws me the error

【问题讨论】:

  • 如果可以控制外部来源,请尝试不加密发送号码。这样你就可以确定它是否与加密/解密过程有关。
  • 是的,我们之前用过这个,没有加密,就是加解密过程。我还与消息来源核实了他传递的字符串确实是我要转换的字符串
  • 您发布的解密方法需要两个字符串参数,但调用只给一个。我错过了什么吗?
  • @NominSim 只是一个错字,为了简单起见,我并没有完全复制/粘贴它的名称。修复它
  • 能否在将底层字节序列转换为字符串之前转储它,即byte[] result = decrypt(keyBytes, decoded)?这可能会提供最好的线索。

标签: java android string encryption base64


【解决方案1】:

明文可能包含看起来像 ASCII 数字但不是 ASCII 数字的字符。有关非 ASCII 数字的数字列表,请参阅 http://www.fileformat.info/info/unicode/category/Nd/list.htm

为了确认,对解密后的文本和硬编码的长字符串执行以下方法,并比较结果:

public static String displayCharValues(String s) {
    StringBuilder sb = new StringBuilder();
    for (char c : s.toCharArray()) {
        sb.append((int) c).append(",");
    }
    return sb.toString();
}

编辑:明文似乎以不可见字符的 BOM (byte order mark) 开头。

【讨论】:

  • 显示结果为65279,50,53,53,49,49,50,50,
  • 这是您的问题。您在字符串的开头有一个额外的不可见字符:fileformat.info/info/unicode/char/feff/index.htm。这是一个字节顺序标记(en.wikipedia.org/wiki/Byte_order_mark
  • 请注意,Java 对 BOM 的处理有时是相当错误的。这是一种耻辱,因为 unicode 处理通常非常先进。
  • 我的字符串末尾有 \n,现在我使用 response = response.trim(); 解决了这个问题;谢谢
【解决方案2】:

注意前面或后面的空格,使用 trim() 处理它们。

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 2012-11-25
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多