0

I've built a simple web application that receives some codes form an end-point and generates a key, from which a QR-Code must be generated from.

The end key its an Uint8Array that needs to be made into a QRCode, I'm using the angularx-qrcode library, and then converting the Uint8Array to a string using String.fromCharCode.apply(null, uintArray) however this approach is proving to not work for my case.

I need to generate the QRCode form the raw HEX values form my array, however using String.fromCharCode it seems to generate UTF-8 characters, thus generating unexpected characters.

So far I've tried using a library to convert the string to 'ISO-8859-1' called iconv-lite but it didn't seem to work.

I also tried converting the string like this decodeURIComponent(escape(encodedString));, however this throws an erros saying invalid URI, probably because the end key has invalid characters that don't work with that function.

The following is an example of my bytes array, its always 20 bytes long. 156,0,0,0,0,0,148,131,114,7,121,81,85,9,0,0,84,69,48,171

After giving it some though I'm thinking that the issue might also be related with the QR-Code library itself, so I looked for a QR-Code library that receives a Uint8Array instead of a string, but I did not managed to find one.

One of my co-workers managed to resolve this issue on the android app by ending the string as ISO-8859-1 instead of UTF-8.

I believe that the solution would be to generate the QRCode from the bytes array directly so that I wouldn't need to bother with character encodings, but if someone knows other approach to resolve this issue I would gladly try it.

I need a RAW string generated from those bytes, for example the first byte is 156, in hex is 9c, so I need the character that represents 9c, however 9c its not a 'regular' ASCII character, that's why String.fromCharCode doesn't work for me, the end string should be exatly 20 bytes long just like the array.

João Eduardo
  • 738
  • 7
  • 21

2 Answers2

0

As I understand you have a trouble generating hex string from byte array? Try this function:

function byteToHex(byte) {
  // convert the possibly signed byte (-128 to 127) to an unsigned byte (0 to 255).
  // if you know, that you only deal with unsigned bytes (Uint8Array), you can omit this line
  const unsignedByte = byte & 0xff;

  // If the number can be represented with only 4 bits (0-15), 
  // the hexadecimal representation of this number is only one char (0-9, a-f). 
  if (unsignedByte < 16) {
    return '0' + unsignedByte.toString(16);
  } else {
    return unsignedByte.toString(16);
  }
}

// bytes is a typed array (Int8Array or Uint8Array)
function toHexString(bytes) {
  // Since the .map() method is not available for typed arrays, 
  // we will convert the typed array to an array using Array.from().
  return Array.from(bytes)
    .map(byte => byteToHex(byte))
    .join('');
}

Credits: https://stackoverflow.com/a/54095276/2036886

Evgeniy Malyutin
  • 1,329
  • 12
  • 16
  • I see your point, but this is not the solution for my case, because I don't need a HEX representation of my Bytes array, I need a RAW string generated from those bytes, for temple the first byte is 156 in hex is 9c so I need the character that represents 9c, however 9c its not a 'regular' ASCII character, that's why `String.fromCharCode` doesn't work for me. – João Eduardo Jan 28 '19 at 12:58
  • 1
    I've edited the question in order to make it clearer. – João Eduardo Jan 28 '19 at 13:07
0

I managed to resolve my issue by using this library: QR-Code-generator

It allows the generation of QRCodes from a bytes array, as well as regular strings.

It is very light-weight and straight forward to use, and it supports many different programming languages. The only downside is that it doesn't support NPM, and its default TypeScript implementation is a little poor, it needed some tweaking to work with my project, but in the end it worked perfectly, it even supports SVG output.

João Eduardo
  • 738
  • 7
  • 21