I have the new Giiker cube i3s which have encrypted state. This was not the case with Giiker cube i3.
The logic to decode the encrypted state can be found here.
https://github.com/kabelbinder/giiker/blob/50db5d58e0417749fe5815e72856b90a1afa43b1/index.js#L326
Below is the logic for decryption and parsing as well.
const turns = {
0: 1,
1: 2,
2: -1,
8: -2,
};
const faces = ['B', 'D', 'L', 'U', 'R', 'F'];
_parseCubeValue (value) {
const state = {
cornerPositions: [],
cornerOrientations: [],
edgePositions: [],
edgeOrientations: []
};
const moves = [];
if (value.getUint8(18) == 0xa7) { // decrypt
var key = [176, 81, 104, 224, 86, 137, 237, 119, 38, 26, 193, 161, 210, 126, 150, 81, 93, 13, 236, 249, 89, 235, 88, 24, 113, 81, 214, 131, 130, 199, 2, 169, 39, 165, 171, 41];
var k = value.getUint8(19);
var k1 = k >> 4 & 0xf;
var k2 = k & 0xf;
for (let i = 0; i < value.byteLength; i++) {
const move = (value.getUint8(i) + key[i + k1] + key[i + k2]) & 0xff;
const highNibble = move >> 4;
const lowNibble = move & 0b1111;
if (i < 4) {
state.cornerPositions.push(highNibble, lowNibble);
} else if (i < 8) {
state.cornerOrientations.push(highNibble, lowNibble);
} else if (i < 14) {
state.edgePositions.push(highNibble, lowNibble);
} else if (i < 16) {
state.edgeOrientations.push(!!(move & 0b10000000));
state.edgeOrientations.push(!!(move & 0b01000000));
state.edgeOrientations.push(!!(move & 0b00100000));
state.edgeOrientations.push(!!(move & 0b00010000));
if (i === 14) {
state.edgeOrientations.push(!!(move & 0b00001000));
state.edgeOrientations.push(!!(move & 0b00000100));
state.edgeOrientations.push(!!(move & 0b00000010));
state.edgeOrientations.push(!!(move & 0b00000001));
}
} else {
moves.push(this._parseMove(highNibble, lowNibble));
}
}
}
else { // not encrypted
for (let i = 0; i < value.byteLength; i++) {
const move = value.getUint8(i)
const highNibble = move >> 4;
const lowNibble = move & 0b1111;
if (i < 4) {
state.cornerPositions.push(highNibble, lowNibble);
} else if (i < 8) {
state.cornerOrientations.push(highNibble, lowNibble);
} else if (i < 14) {
state.edgePositions.push(highNibble, lowNibble);
} else if (i < 16) {
state.edgeOrientations.push(!!(move & 0b10000000));
state.edgeOrientations.push(!!(move & 0b01000000));
state.edgeOrientations.push(!!(move & 0b00100000));
state.edgeOrientations.push(!!(move & 0b00010000));
if (i === 14) {
state.edgeOrientations.push(!!(move & 0b00001000));
state.edgeOrientations.push(!!(move & 0b00000100));
state.edgeOrientations.push(!!(move & 0b00000010));
state.edgeOrientations.push(!!(move & 0b00000001));
}
} else {
moves.push(this._parseMove(highNibble, lowNibble));
}
}
}
return {state, moves};
}
_parseMove (faceIndex, turnIndex) {
const face = faces[faceIndex - 1];
const amount = turns[turnIndex - 1];
let notation = face;
switch (amount) {
case 2: notation = `${face}2`; break;
case -1: notation = `${face}'`; break;
case -2: notation = `${face}2'`; break;
}
return {face, amount, notation};
}