{"record":{"id":"2312769358ec503c","repo":"chinabugotech/hutool","slug":"base58-checksum-is-invalid","errorCode":null,"errorMessage":"Base58 checksum is invalid","messagePattern":"Base58 checksum is invalid","errorType":"validation","errorClass":"ValidateException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/codec/Base58.java","lineNumber":100,"sourceCode":"\t * @return 解码后的bytes\n\t */\n\tpublic static byte[] decode(CharSequence encoded) {\n\t\treturn Base58Codec.INSTANCE.decode(encoded);\n\t}\n\n\t/**\n\t * 验证并去除验证位和版本位\n\t *\n\t * @param data        编码的数据\n\t * @param withVersion 是否包含版本位\n\t * @return 载荷数据\n\t */\n\tprivate static byte[] verifyAndRemoveChecksum(byte[] data, boolean withVersion) {\n\t\tfinal byte[] payload = Arrays.copyOfRange(data, withVersion ? 1 : 0, data.length - CHECKSUM_SIZE);\n\t\tfinal byte[] checksum = Arrays.copyOfRange(data, data.length - CHECKSUM_SIZE, data.length);\n\t\tfinal byte[] expectedChecksum = checksum(payload);\n\t\tif (false == Arrays.equals(checksum, expectedChecksum)) {\n\t\t\tthrow new ValidateException(\"Base58 checksum is invalid\");\n\t\t}\n\t\treturn payload;\n\t}\n\n\t/**\n\t * 数据 + 校验码\n\t *\n\t * @param version 版本，{@code null}表示不添加版本位\n\t * @param payload Base58数据（不含校验码）\n\t * @return Base58数据\n\t */\n\tprivate static byte[] addChecksum(Integer version, byte[] payload) {\n\t\tfinal byte[] addressBytes;\n\t\tif (null != version) {\n\t\t\taddressBytes = new byte[1 + payload.length + CHECKSUM_SIZE];\n\t\t\taddressBytes[0] = (byte) version.intValue();\n\t\t\tSystem.arraycopy(payload, 0, addressBytes, 1, payload.length);\n\t\t} else {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/codec/Base58.java#L82-L118","documentation":"Base58 decoding (with checksum) splits the decoded bytes into payload + 4-byte trailing checksum, recomputes the checksum of the payload, and compares. A mismatch means the input was corrupted, truncated, or is not a valid Base58Check value, and ValidateException is thrown. This is the standard Bitcoin-style Base58Check integrity guard.","triggerScenarios":"Base58.decode / decodeChecked on a string whose last 4 bytes do not equal the SHA256-double hash of the payload; a typo in a Base58 address; using a raw (unchecked) Base58 string with a checked-decode API.","commonSituations":"Handling cryptocurrency addresses/keys that the user mistyped; reading Base58 from a transport that dropped/corrupted characters; mixing checked vs unchecked encode/decode.","solutions":["Confirm the input was produced by the checked encoder (Base58.encodeChecked); if it is raw Base58 use the non-checked decode path.","Re-verify the source string character-for-character (single typo invalidates the checksum by design).","Catch ValidateException and surface a 'corrupt input' error to the user rather than retrying."],"exampleFix":"// before\nbyte[] payload = Base58.decodeChecked(userInput);\n// after\ntry { byte[] payload = Base58.decodeChecked(userInput); }\ncatch (ValidateException e) { throw new IllegalArgumentException(\"address corrupt or mistyped\", e); }","handlingStrategy":"try-catch","validationCode":"// cannot validate checksum without decoding; ensure input came from encodeChecked\nif (input == null || input.isEmpty()) throw new IllegalArgumentException(\"empty base58\");","typeGuard":null,"tryCatchPattern":"try { return Base58.decodeChecked(s); } catch (ValidateException e) { throw new IllegalArgumentException(\"corrupt Base58Check input\", e); }","preventionTips":["Use encodeChecked/decodeChecked in pairs.","Surface checksum failures as user-facing input errors."],"tags":["base58","checksum","codec","validation"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}