mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-22 15:56:16 -04:00
103 lines
2.3 KiB
JavaScript
103 lines
2.3 KiB
JavaScript
/**
|
|
* Bit rotation functions.
|
|
*
|
|
* @author n1474335 [n1474335@gmail.com]
|
|
* @copyright Crown Copyright 2016
|
|
* @license Apache-2.0
|
|
*
|
|
* @todo Support for UTF16
|
|
*/
|
|
|
|
|
|
/**
|
|
* Runs rotation operations across the input data.
|
|
*
|
|
* @param {byteArray} data
|
|
* @param {number} amount
|
|
* @param {function} algo - The rotation operation to carry out
|
|
* @returns {byteArray}
|
|
*/
|
|
export function rot(data, amount, algo) {
|
|
const result = [];
|
|
for (let i = 0; i < data.length; i++) {
|
|
let b = data[i];
|
|
for (let j = 0; j < amount; j++) {
|
|
b = algo(b);
|
|
}
|
|
result.push(b);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Rotate right bitwise op.
|
|
*
|
|
* @param {byte} b
|
|
* @returns {byte}
|
|
*/
|
|
export function rotr(b) {
|
|
const bit = (b & 1) << 7;
|
|
return (b >> 1) | bit;
|
|
}
|
|
|
|
/**
|
|
* Rotate left bitwise op.
|
|
*
|
|
* @param {byte} b
|
|
* @returns {byte}
|
|
*/
|
|
export function rotl(b) {
|
|
const bit = (b >> 7) & 1;
|
|
return ((b << 1) | bit) & 0xFF;
|
|
}
|
|
|
|
|
|
/**
|
|
* Rotates a byte array to the right by a specific amount as a whole, so that bits are wrapped
|
|
* from the end of the array to the beginning.
|
|
*
|
|
* @param {byteArray} data
|
|
* @param {number} amount
|
|
* @returns {byteArray}
|
|
*/
|
|
export function rotrCarry(data, amount) {
|
|
const result = [];
|
|
let carryBits = 0,
|
|
newByte;
|
|
|
|
amount = amount % 8;
|
|
for (let i = 0; i < data.length; i++) {
|
|
const oldByte = data[i] >>> 0;
|
|
newByte = (oldByte >> amount) | carryBits;
|
|
carryBits = (oldByte & (Math.pow(2, amount)-1)) << (8-amount);
|
|
result.push(newByte);
|
|
}
|
|
result[0] |= carryBits;
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Rotates a byte array to the left by a specific amount as a whole, so that bits are wrapped
|
|
* from the beginning of the array to the end.
|
|
*
|
|
* @param {byteArray} data
|
|
* @param {number} amount
|
|
* @returns {byteArray}
|
|
*/
|
|
export function rotlCarry(data, amount) {
|
|
const result = [];
|
|
let carryBits = 0,
|
|
newByte;
|
|
|
|
amount = amount % 8;
|
|
for (let i = data.length-1; i >= 0; i--) {
|
|
const oldByte = data[i];
|
|
newByte = ((oldByte << amount) | carryBits) & 0xFF;
|
|
carryBits = (oldByte >> (8-amount)) & (Math.pow(2, amount)-1);
|
|
result[i] = (newByte);
|
|
}
|
|
result[data.length-1] = result[data.length-1] | carryBits;
|
|
return result;
|
|
}
|