@Test
public void testMidJoin() {

  byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
  byte[] data = reference.clone();
  Random random = new Random(RANDOM_SEED);
  // Encrypt
  int offset = 0;
  while (offset < data.length) {
    int bytes = 1 + random.nextInt(4095);
    bytes = Math.min(bytes, data.length - offset);
    encryptCipher.updateInPlace(data, offset, bytes);
    offset += bytes;
  }
  // Verify
  int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
  assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
      .isTrue();
  // Setup decryption from random location
  offset = random.nextInt(4096);
  decryptCipher = new AesFlushingCipher(Cipher.DECRYPT_MODE, KEY, NONCE, offset + START_OFFSET);
  int remainingLength = data.length - offset;
  int originalOffset = offset;
  // Decrypt
  while (remainingLength > 0) {
    int bytes = 1 + random.nextInt(4095);
    bytes = Math.min(bytes, remainingLength);
    decryptCipher.updateInPlace(data, offset, bytes);
    offset += bytes;
    remainingLength -= bytes;
  }
  // Verify
  int differingByteCount = getDifferingByteCount(reference, data, originalOffset);
  assertThat(differingByteCount).isEqualTo(0);
}