function hashing = twist(mes,L,starlet,ringlength,numofhash,layernum)%L is number of different characters in alphabet,starlet is starting character of alphabet in decimal rep(ascii), ringlength is number of bits in each ring, numofhash is the number of desired hash numbers, layernum is min fix amount of layers
mes=double(mes)-starlet;%decimal rep of each letter in message (first letter in alphabet=0)
h=(log(L-1))/(log(2));
s=floor(h)+1; % number of bits per letter
if s==1;
    s=2;
end;
n=length(mes); %n=number of letters in message
N=s*n; %N=number of bits in message, for s bit rep of letters
lets=dec2bin(0:L-1,s);%to initialize set of all possible letters in binary form
message=dec2bin(0,N);%to initialize message
hash=zeros(s,n+1);%to initialize matrix to be xored
hashlet=zeros(1,s);%to initialize vector represented final hash output
hashout=numofhash*s;%number of bits of output hash
if rem(ringlength,hashout*log(2))>0;%if ringlength is not of correct size for model
    if ringlength>=hashout;
    ringlength=(2^(floor(log(floor(ringlength/(hashout)))/log(2))+1))*hashout;
    else ringlength=2*hashout;
    end;
else
    ringlength=ringlength;
end;
unpadmes=(floor((N-1)/ringlength)+1);%number of layers needed to fit all bits of message
if unpadmes==layernum %if minimum layer amount=number of layers needed to fit all bits of message
    level=layernum+1;%actual amount of layers in petri-dish is one more than minimum amount
elseif unpadmes<layernum;%if minimum layer amount<number of layers needed to fit all bits of message
    level=layernum;%actual amount of layers in petri-dish is equal to the minimum amount
else%if minimum layer amount>number of layers needed to fit all bits of message
    level=unpadmes+1;%actual amount of layers in petri-dsih =number of layers needed to fit all bits of message +1
end;
portion=level-unpadmes+1;%fraction of message shifted for each additional layer that does not include first run through of the bits of the message
for p=1:n; %to determine what binary number each letter in the message is
   for e=1:L;
      for g=1:s;
          if ((mes(p)<e) && (mes(p)>e-2)); 
              message((s*p)-(s-g))=num2str(lets(e,g));
          end;
      end;
   end;
end;
messaget=message; %to pad level that first run of message ends on
if N~=(unpadmes*ringlength);%if all bits of message do not fill a multiple of the ringlength completely
    trep=floor((unpadmes*ringlength)/N);%trep is the number of times the full message must be repeated +1 to fill ring with the last part of the 1st run through of the message
    for i=1:trep;
       messaget=[messaget,message];
   end;
   for j=1:((trep+1)*N)-(unpadmes*ringlength);%for all spots on each ring of the layers needed to fit all bits of message
       messaget(((trep+1)*N)-j+1)=[];%repeat the bits of the message for each additional spot that the message does not fill
   end;
end;
messaget=reshape(messaget,ringlength,unpadmes)';%make matrix of bits of message(with padding) so that each row corresponds to each layer and each column corresponds to each spot on the ring
for i=1:unpadmes;
    messagep(i,:)=messaget(i,:);%call messaget, messagep
end;
%to pad remaining levels that inital run of message does not fall on
remi=rem(N,portion); 
if remi~=0;%if when the message is divided into portions for shifting, the message can not be evenly divided such that an equal number of bits are in each portion
    newmessage=message;
    for j=2:n;%sum up the decimal values (after shifted for starting letter of alphabet), of all the letters in the message
        mes(j)=j*mes(j);
        mes(1)=mes(1)+mes(j);
    end;
    for i=1:portion-remi;%for additional bits needed to make message evenly divided into needed portions
        remmin=rem(mes(1),2);%additional ith bit is the remainder of (the ith sum (1st sum is of all decimal values of all the letters in the message)/2) 
        newmessage=[newmessage,dec2bin(remmin)];%newmessage is the message with additional padding to be divided into portions
        mes(1)=((mes(1)+remmin)/2);%(i+1)th sum is (the ith sum + remainder when divided by 2)divided by 2 
    end;
else newmessage=message;
end;
NS=length(newmessage);%NS is the number of bits in newmessage(message with additional padding so message can be divided onto portions)
newmessage=[newmessage,newmessage];
for i=1:portion-1;%for each level that original run of message doesn't fit on
    if NS>=ringlength %if shifted message larger than ringlength
       for j=1:ringlength;%for just the spots on the ring
           messagets(i,j)=newmessage(((NS*i)/(portion))+j);%each spot is filled with corresponding bit for shifted message (by portion)
       end;
    elseif NS<ringlength; %if shifted message smaller than ringlength  
           ttrep=floor((ringlength-1)/NS)+1;%number of times shifted message needs to be repeated
           for j=1:ttrep;%for the number of times shifted message needs to be repeated
               for v=NS:-1:1;%for all the bits of the message with extra padding
                   if (NS*(j-1))+(NS-v+1)<=ringlength;%if a spot on the ring still needs to be filled
                      messagets(i,(j*NS)-v+1)=newmessage(((NS*i)/(portion))+(NS-v+1));%each spot is filled with bit of shifted message repeated
                   end;
               end;
           end;
    end;
end;
for i=unpadmes+1:level;%for each level that original run of message doesn't fit on
    messagep(i,:)=messagets(i-unpadmes,:);%messagep for those layers is filled with shifted message with needed padding
end;
finalmessage=reshape(messagep,1,ringlength*level);%final message is a row vector of messagep (each row is brought up to first row, such that all the first bits of the first character are next each other, and then the bits of the next letter, etc., rows read accross starting with first layer through last layer)
times=(log(ringlength/hashout))/(log(2));%number of times to xor from outside ring to inside ring
for g=1:level*ringlength; %to initiliaze first set of numbers to be xored
    hash(1,g)=str2num(finalmessage(g));%to convert first set of numbers to be xored into numbers (from strings)
end;
if times>0; %if the circumference isn't equal to bits of hash output, xor inward until have amount of bits of hash output
   for j=2:times+1;%for each time the message must be xored inward
       for i=1:((ringlength*level)/(2^(j-1))); %for every other bit on the ring being xored
           hash(j,i)=xor(hash((j-1),((2*i)-1)),hash((j-1),(2*i)));%xor that bit with the bit next to it
        end;
    end;
end;
hash=hash(times+1,:);%make matrix of bits of each layers hash values (each layer is a row)
for i=1:hashout;%for each bit of final hash output
    for j=1:level-1;%for each level (not counting first level)
        hash(i)=xor(hash(i),(hashout*j)+1);%xor each hash value with xored hash value on the layer above (just hash value on first level)
    end;
end;
for o=1:numofhash;%for all of the desired character outputs
    for h=1:s;%for each bit of a character
        hashlet(o,h)=(hash(s*(o-1)+h))';%organize binary hash outputs in a matrix, with each character (in binary form) on a seperate row
    end;
end;
hashing=(bin2dec(num2str(hashlet)))'+ starlet;%convert each binary rep of each hash character into its correspondng ascii decimal value