function y = ehtScramble(x,scramInit)
%ehtScramble Scramble and descramble the binary input
%
%   Y = ehtScramble(X,SCRAMINIT) scrambles and descrambles the binary
%   input X using a frame-synchronous scrambler.
%
%   Y is a binary column vector or a matrix of type int8 or double with the
%   same size and type as the input X.
%
%   X is a binary column vector or a matrix of type int8 or double and is
%   scrambled with a length-2047 frame-synchronous scrambler. Each column
%   of X is scrambled independently with the same initial state. The
%   frame-synchronous scrambler uses the generator polynomial defined in
%   IEEE P802.11be/D01.0, Section 36.3.13.2. The same scrambler structure
%   is used to scramble bits at the transmitter and descramble bits at the
%   receiver.
%
%   SCRAMINIT is the initial state of the scrambler. It is an integer
%   between 1 and 2047 inclusive, or a corresponding 11-by-1 column vector
%   of binary bits of type int8 or double. The mapping of the
%   initialization bits on scrambler schematic X1 to X11 is specified in
%   IEEE P802.11be/D1.0, Section 36.3.13.2.
%   
%   Example: 
%   % Scramble and descramble bits.
%
%   scramInit = 93; % Initialization value
%   input = randi([0,1],1000,1);
%   scrambledData = ehtScramble(input,scramInit);
%   descrambledData = ehtScramble(scrambledData,scramInit);
%   isequal(input,descrambledData)
%
%   See also ehtData.

%   Copyright 2020-2021 The MathWorks, Inc.

inputClass = class(x);
buffSize = min(2047,size(x,1));
I = zeros(buffSize,1,'int8');

if isscalar(scramInit)
    scramInit = de2bi(scramInit,11,'left-msb').'; 
end

% Scrambling sequence generated using generator polynomial
for d = 1:buffSize
    I(d) = xor(scramInit(1),scramInit(3)); % x11 xor x9
    scramInit(1:end-1) = scramInit(2:end); % Left-shift
    scramInit(11) = I(d);                  % Update x1
end

% Generate a periodic sequence from I to be xor-ed with the input
if isempty(coder.target)
    scramblerSequence = repmat(I,ceil(size(x,1)/buffSize),1);
    y = cast(xor(x,scramblerSequence(1:size(x,1))),inputClass);
else % Codegen branch
    y = coder.nullcopy(cast(zeros(size(x)),inputClass));
    for j = 1:size(x,2)
        k = 0;
        for i = 1:size(x,1)
            if k == buffSize
                k = 1;
            else
                k = k + 1;
            end
            y(i,j) = xor(x(i,j),I(k));
        end
    end
end

end