-1

I am currently trying to work with a private API, and it returns some data. I can make it return any data I want, but it comes in a non-standard (to my knowledge) hexadecimal format. Decoding it as ASCII does not provide the correct result. For example:

This is a hexadecimal string which the API returns.

64 67 66 61 60 63 62 6D 6C 6F 6E 69 68 6B 6A 75 74 77 76 71 70 73 72 7D 7C 7F

This hexadecimal string, when converted, would read as the full English alphabet in lowercase. However, as you can possibly tell from just looking at the string, it is not an ASCII string. What format is this hex in, and how can I decode it (specifically in JS)?

  • Seems like you are trying "crack" an encryption, in which case your best chance is to debug existing code that uses that api. – vanowm Aug 29 '22 at 15:08
  • Does this answer your question? [Converting byte array to string in javascript](https://stackoverflow.com/questions/3195865/converting-byte-array-to-string-in-javascript) – starball Aug 29 '22 at 17:11

1 Answers1

0

It seems to be XOR'ed with number 5

const data = "64 67 66 61 60 63 62 6D 6C 6F 6E 69 68 6B 6A 75 74 77 76 71 70 73 72 7D 7C 7F";

console.log(data.split(" ").map(n => String.fromCharCode(parseInt(n, 16) ^ 5)).join(""));

Knowing the expected result, we can compare existing number with expected to see the difference and find a pattern.

Let's compare first number 64 with letter a (61) in binary:

0x64 = 01100100
0x61 = 01100001

now the second number 67 with letter b (62):

0x67 = 01100111
0x62 = 01100010

and third number 66 with letter c (63):

0x66 = 01100110
0x63 = 01100011

If you look closely, you can see that there is a pattern, bit 0 and 2 (bits count from right side) are not matching. So, if we convert binary 00000101 into decimal we'll get number 5

const data = "64 67 66 61 60 63 62 6D 6C 6F 6E 69 68 6B 6A 75 74 77 76 71 70 73 72 7D 7C 7F";

data.split(" ").forEach((n,i) =>
{
  const number = parseInt(n, 16),
        numberExpected = "a".charCodeAt(0) + i,
        char = String.fromCharCode(number),
        charExpected = String.fromCharCode(numberExpected),
        xor = number ^ numberExpected,
        result = number ^ xor,
        charResult = String.fromCharCode(result);

  console.log(`${char} (${n}) | expected: ${charExpected} (${numberExpected.toString(16)}) | XOR difference: ${xor} | result: ${charResult}`);
});
.as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}
vanowm
  • 9,466
  • 2
  • 21
  • 37
  • Thank you so much! I know that comments aren't supposed to say "thank you" but I've needed this answer. I really appeciate it. – madeline.xoxo Sep 02 '22 at 18:46