{"record":{"id":"e21ec17327715788","repo":"egametang/ET","slug":"the-binary-key-cannot-have-an-odd-number-of-digits","errorCode":null,"errorMessage":"The binary key cannot have an odd number of digits: {0}","messagePattern":"The binary key cannot have an odd number of digits: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.core/Scripts/Core/Share/Helper/StringHelper.cs","lineNumber":42,"sourceCode":"\t\t}\n\n\t\tpublic static byte[] ToByteArray(this string str)\n\t\t{\n\t\t\tbyte[] byteArray = Encoding.Default.GetBytes(str);\n\t\t\treturn byteArray;\n\t\t}\n\n\t    public static byte[] ToUtf8(this string str)\n\t    {\n            byte[] byteArray = Encoding.UTF8.GetBytes(str);\n            return byteArray;\n        }\n\n\t\tpublic static byte[] HexToBytes(this string hexString)\n\t\t{\n\t\t\tif (hexString.Length % 2 != 0)\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(String.Format(CultureInfo.InvariantCulture, \"The binary key cannot have an odd number of digits: {0}\", hexString));\n\t\t\t}\n\n\t\t\tvar hexAsBytes = new byte[hexString.Length / 2];\n\t\t\tfor (int index = 0; index < hexAsBytes.Length; index++)\n\t\t\t{\n\t\t\t\tstring byteValue = \"\";\n\t\t\t\tbyteValue += hexString[index * 2];\n\t\t\t\tbyteValue += hexString[index * 2 + 1];\n\t\t\t\thexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);\n\t\t\t}\n\t\t\treturn hexAsBytes;\n\t\t}\n\n\t\tpublic static string Fmt(this string text, params object[] args)\n\t\t{\n\t\t\treturn string.Format(text, args);\n\t\t}\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.core/Scripts/Core/Share/Helper/StringHelper.cs#L24-L60","documentation":"StringHelper.HexToBytes parses a hex string two characters at a time into bytes. An odd number of characters means the string is not valid hex (each byte needs two digits), so it throws ArgumentException listing the offending input.","triggerScenarios":"Passing a hex key/hash string with an odd length, e.g. a truncated MD5/AES key, a leading zero dropped, or a copy-paste that lost a character.","commonSituations":"Mis-typed secret/hex token in config, key generated by a tool that strips leading zeros, or binary data rendered as hex without zero-padding.","solutions":["Validate hexString.Length is even before calling HexToBytes.","Re-derive the key from its source and copy the full string.","Left-pad a single-nibble value with a leading '0' if you dropped one."],"exampleFix":"// before\nbyte[] key = token.HexToBytes();\n// after\nif (string.IsNullOrEmpty(token) || token.Length % 2 != 0 || !token.All(c => \"0123456789abcdefABCDEF\".Contains(c)))\n    throw new ArgumentException(\"invalid hex token\", nameof(token));\nbyte[] key = token.HexToBytes();","handlingStrategy":"validation","validationCode":"static bool IsHex(string s) => s.Length % 2 == 0 && s.All(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));\nif (!IsHex(hex)) throw new ArgumentException(\"not valid hex\", nameof(hex));\nbyte[] b = hex.HexToBytes();","typeGuard":"public static bool IsValidHexString(string s) => !string.IsNullOrEmpty(s) && s.Length % 2 == 0 && s.All(c => \"0123456789abcdefABCDEF\".IndexOf(c) >= 0);","tryCatchPattern":"try { return hex.HexToBytes(); }\ncatch (ArgumentException) { throw new ArgumentException(\"malformed hex key in config\", nameof(hex)); }","preventionTips":["Store keys in binary-safe formats or full even-length hex.","Validate config keys at startup, not on first use.","Never hand-edit a hex key character by character."],"tags":["string","encoding","argument","csharp"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}