Test (v2)

Revision 2 of this benchmark created on


Setup

const getCRC = (byteArr) => {
  const PRESET_VALUE = 0xFFFF
  const POLYNOMIAL = 0x8408

  let uiCrcValue = PRESET_VALUE

  // eslint-disable-next-line no-plusplus
  for (let ucI = 0; ucI < byteArr.length; ucI++) {
    uiCrcValue ^= byteArr[ucI]

    // eslint-disable-next-line no-plusplus
    for (let ucJ = 0; ucJ < 8; ucJ++) {
      if (uiCrcValue & 0x0001) {
        uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL
      } else {
        uiCrcValue >>= 1
      }
    }
  }

  return uiCrcValue
}

const isValidCRC = (byteString) => {
  if (byteString.length % 2 !== 0) {
    return false;
  }

  const byteStringArr = []
  for (let i = 0; i < byteString.length; i += 2) {
    byteStringArr.push(byteString.substring(i, i + 2))
  }
  
	const head = 1
	const addr = 1
	const cmd = 2
	const len = 1
	const status = 1
	const crcLength = 2

	if (byteStringArr.length < head + addr + cmd + len + status + crcLength) {
    return false;
	}

	const crcBytes = byteStringArr.slice(byteStringArr.length - crcLength).map((b) => parseInt(b, 16))
	const dataBytesStr = byteStringArr.slice(0, byteStringArr.length - crcLength)
	const data = dataBytesStr.map((b) => parseInt(b, 16))

	const crc = getCRC(data)

	if (crcBytes[0] !== ((crc >> 8) & 0xFF)) {
    return false;
	}

	if (crcBytes[1] !== (crc & 0xFF)) {
    return false;
	}

	return true;
}

const splitFrames = (byteString, frames = []) => {
	// head (1) + add (1) + cmd (2) + len (1)
	const requiredBytesBeforeCRC = 1 + 1 + 2 + 1;

	if (byteString.length % 2 !== 0 || byteString.length < requiredBytesBeforeCRC * 2) {
    return frames;
  }

  const byteStringArr = []
  for (let i = 0; i < byteString.length; i += 2) {
    byteStringArr.push(byteString.substring(i, i + 2))
  }

	const startIndex = requiredBytesBeforeCRC + 2
	const lastPossibleIndex = byteStringArr.length;

	for (let rightCursor = startIndex; rightCursor <= lastPossibleIndex; rightCursor++) {
		const possibleFrame = byteStringArr.slice(0, rightCursor);
		if (isValidCRC(possibleFrame.join(''))) {
			frames.push(possibleFrame)
			return splitFrames(
				byteString.slice(rightCursor * 2), // byte -> char
				frames
			)
		}
	}

	return frames;
}

Test runner

Ready to run.

Testing in
TestOps/sec
Long
splitFrames('CF0000010112421DCF00000201009EEACF478112487249CF0000010112421D313131')
ready
Short
splitFrames('CF0000010112421DCF00000201009EEA')
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.