Bifid Cipher

October 13, 2009

Instead of a square, we find it easier to represent the key as a string:

(define key "ABCDEFGHIKLMNOPQRSTUVWXYZ")
; row        1111122222333334444455555
; column     1234512345123451234512345

Then ltr->rc and rc->ltr translate between letters and row/column digits:

(define (ltr->rc key c)
  (let ((idx (string-index c key)))
    (cons (+ (quotient idx 5) 1)
          (+ (modulo idx 5) 1))))

(define (rc->ltr key r c)
  (let ((idx (+ (* (- r 1) 5) c -1)))
    (string-ref key idx)))

Before enciphering it, we prepare the plain-text by removing non-alphabetic characters, replacing J with I, and converting to upper-case:

(define (prep text)
  (define (j->i c)
    (if (char-ck=? c #\J) #\I (char-upcase c)))
  (let loop ((cs (string->list text)) (ps '()))
    (cond ((null? cs) (reverse ps))
          ((char-alphabetic? (car cs))
            (loop (cdr cs) (cons j->i (car cs) ps)))
          (else (loop (cdr cs) ps)))))

Encipher works in two phases. The first let makes a list of row/column pairs, and the second let loops over the list converting the digits back to letters:

(define (encipher key plain-text)
  (let ((rcs (map (lambda (c) (ltr->rc key c)) (prep plain-text))))
    (let loop ((xs (append (map car rcs) (map cdr rcs))) (result '()))
      (if (null? xs) (list->string (reverse result))
        (loop (cddr xs) (cons (rc->ltr key (car xs) (cadr xs)) result))))))

Decipher only looks harder. Xs computes the row/column pairs, which are then split into rs and cs, and the second let loops over the digit pairs converting them to letters:

(define (decipher key cipher-text)
  (let* ((len (string-length cipher-text))
         (xs (let loop ((cs (string->list cipher-text)) (ps '()))
               (if (null? cs) (reverse ps)
                 (let ((x (ltr->rc key (car cs))))
                   (loop (cdr cs) (cons (cdr x) (cons (car x) ps)))))))
         (rs (take len xs)) (cs (drop len xs)))
    (let loop ((rs rs) (cs cs) (ps '()))
      (if (null? rs) (list->string (reverse ps))
        (loop (cdr rs) (cdr cs) (cons (rc->ltr key (car rs) (car cs)) ps))))))

We used take, drop and string-index from the Standard Prelude. You can run the code at http://programmingpraxis.codepad.org/rvI0TxI7.

Pages: 1 2

22 Responses to “Bifid Cipher”

  1. Remco Niemeijer said

    My Haskell solution (see http://bonsaicode.wordpress.com/2009/10/13/278/ for a version with comments):

    import Data.Char
    import Data.List
    import Data.List.HT hiding (unzip)
    import Data.Map ((!), fromList)
    
    alphabet :: String
    alphabet = delete 'J' ['A'..'Z']
    
    indices :: [(Int, Int)]
    indices = zip (concatMap (replicate 5) [1..5]) (cycle [1..5])
    
    toIndex :: Char -> (Int, Int)
    toIndex c = fromList (zip alphabet indices) ! c
    
    fromIndex :: [Int] -> Char
    fromIndex [x, y] = fromList (zip indices alphabet) ! (x, y)
    fromIndex _      = undefined
    
    prepare :: String -> String
    prepare = filter (`elem` alphabet) . replace "J" "I" . map toUpper
    
    encode :: String -> String
    encode = map fromIndex . sliceVertical 2 . uncurry (++) .
             unzip . map toIndex . prepare
    
    decode :: String -> String
    decode xs = map fromIndex . sliceHorizontal (length xs) .
                concatMap ((\(x, y) -> [x, y]) . toIndex) $ prepare xs
    
  2. liesen said
    import Data.Char
    import Data.List
    import Data.Maybe (fromJust)
    
    alphabet = delete 'J' ['A'..'Z']
    
    normalize = filter (`elem` alphabet) . replace1 'J' 'I' . map toUpper
      where
        replace1 _ _ []     = []
        replace1 x y (z:zs) = (if x == z then y else z) : replace1 x y zs
    
    encode1 :: (Int, Int) -> Char
    encode1 = fromJust . flip lookup ((map (`divMod` 5) [0..]) `zip` alphabet)
    
    decode1 :: Char -> (Int, Int)
    decode1 = fromJust . flip lookup (alphabet `zip` (map (`divMod` 5) [0..]))
    
    encode, decode :: String -> String
    encode = map encode1 . pair . uncurry (++) . unzip . map decode1 . normalize 
      where
        pair (x:y:zs) = (x, y) : pair zs
        pair _        = []
    
    decode s = map encode1 $ uncurry zip
                           $ splitAt n
                           $ foldr (\(x, y) zs -> x : y : zs) []
                           $ map decode1
                           $ normalize s
      where
        n = length s
    

    I need to check out Data.List.HT.

  3. […] Praxis – Bifid Cipher By Remco Niemeijer Today’s Programming Praxis problem is another cipher, specifically Bifid’s cipher. Let’s get […]

  4. Well here’s my t-sql version

    CREATE FUNCTION [dbo].[DeEnCrypt]
    (
    — Add the parameters for the function here
    @string nvarchar(max), @bit bit
    )
    RETURNS nvarchar(max)
    AS
    BEGIN
    — Declare the return variable here

    declare @table table (y char(1), x char(1), Chr char(1))
    declare @i int,
    @count int,
    @x nvarchar(max), –holds x coordinate
    @y nvarchar(max), –holds y coordinate
    @catnum nvarchar(max), –concatinated x and y coordinates
    @cat nvarchar(max) –end result

    insert into @table values (1,1,’A’)
    insert into @table values (1,2,’B’)
    insert into @table values (1,3,’C’)
    insert into @table values (1,4,’D’)
    insert into @table values (1,5,’E’)
    insert into @table values (2,1,’F’)
    insert into @table values (2,2,’G’)
    insert into @table values (2,3,’H’)
    insert into @table values (2,4,’I’)
    insert into @table values (2,5,’K’)
    insert into @table values (3,1,’L’)
    insert into @table values (3,2,’M’)
    insert into @table values (3,3,’N’)
    insert into @table values (3,4,’O’)
    insert into @table values (3,5,’P’)
    insert into @table values (4,1,’Q’)
    insert into @table values (4,2,’R’)
    insert into @table values (4,3,’S’)
    insert into @table values (4,4,’T’)
    insert into @table values (4,5,’U’)
    insert into @table values (5,1,’V’)
    insert into @table values (5,2,’W’)
    insert into @table values (5,3,’X’)
    insert into @table values (5,4,’Y’)
    insert into @table values (5,5,’Z’)

    set @bit=0

    if (@bit=0)
    begin
    –set @string=’apples’ –CNDEVX
    set @x=”
    set @y=”
    set @cat=”

    set @count=LEN(@string)
    set @i=1

    while (@i<=@count)
    begin

    select @x=@x+x, @y=@y+y
    from @table
    where Chr = SUBSTRING(@string,@i,1)

    set @i=@i+1
    end

    set @catnum=@y+@x
    set @i=1

    set @count=LEN(@catnum)

    while (@i<=@count)
    begin

    select @y=SUBSTRING(@catnum,@i,1),
    @x=SUBSTRING(@catnum,@i+1,1)

    select @cat=@cat+Chr
    from @table
    where x=@x and y=@y

    –select @y, @x

    set @i=@i+2
    end

    end
    else
    begin

    –set @string='CNDEVX'
    set @x=''
    set @y=''
    set @cat=''
    set @catnum=''

    set @count=LEN(@string)
    set @i=1

    while (@i<=@count)
    begin

    select @catnum=@catnum+y+x
    from @table
    where Chr=SUBSTRING(@string,@i,1)

    set @i=@i+1
    end

    set @y=LEFT(@catnum,LEN(@catnum)/2)
    set @x=right(@catnum,LEN(@catnum)/2)

    set @count=LEN(@y)
    set @i=1

    while (@i<=@count)
    begin

    select @cat=@cat+Chr
    from @table
    where x=SUBSTRING(@x,@i,1)
    and y=SUBSTRING(@y,@i,1)

    set @i=@i+1
    end

    end

    return @cat

    — Return the result of the function

    END

    GO

  5. meecrob said

    Hey, I’m pretty new to python and first time on praxis, but here is the python solution:

    http://pastebin.com/f7f1072a5

    P.S I have no idea what is supposed to be done with J.

  6. Arnar said

    Here’s another Python solution. I wrote it without looking at meecrob’s one, it is interesting to see that they are still quite similar.

    def blocks(data, blocksize):
    “””Generator that yields elements from xs in blocks.”””
    assert(len(data) % blocksize == 0)
    for i in xrange(0, len(data), blocksize):
    yield data[i:i+blocksize]

    key1 = list(blocks(“ABCDEFGHIKLMNOPQRSTUVWXYZ”, 5))
    key2 = list(blocks(“37FBO7T20KZUMXYHLS196QW4AVIDGNJPCRE5”, 6))

    def code2char(a, b, key):
    return key[a][b]

    def char2code(c, key):
    c = c.upper()
    r = [c in row for row in key]
    assert any(r)
    a = r.index(True)
    b = key[a].index(c)
    return a, b

    def encrypt(s, key):
    codes = map(lambda x: char2code(x,key), s)
    a, b = zip(*codes)
    d = blocks(a+b, 2)
    c = “”.join(map(lambda (a,b): code2char(a, b, key), d))
    return c

    def decrypt(c, key):
    d = sum(map(lambda x: char2code(x,key), c), ())
    h = len(d)/2
    a, b = d[:h], d[h:]
    codes = zip(a, b)
    s = “”.join(map(lambda (a,b): code2char(a,b,key), codes))
    return s

  7. Arnar said

    Hm, sorry about code formatting (can it be fixed?).

    Here’s the code: http://pastie.org/658185

  8. Leftware said

    This is my dirty C# implementation:

    public static string Bifid(string entrada) {
    var filas = “1111122222333334444455555”;
    var cols = “1234512345123451234512345”;
    var alfa = “abcdefghiklmnopqrstuvwxyz”;

    entrada = entrada.ToLower();

    var arr1 = new char[entrada.Length];
    var arr2 = new char[entrada.Length];

    for (int i = 0; i < entrada.Length; i++) {
    var ind = alfa.IndexOf(entrada[i]);
    arr1[i] = filas[ind];
    arr2[i] = cols[ind];
    }
    var arr3 = new char[entrada.Length * 2];
    Array.ConstrainedCopy(arr1, 0, arr3, 0, arr1.Length);
    Array.ConstrainedCopy(arr2, 0, arr3, arr1.Length, arr2.Length);
    var sb = new StringBuilder();
    for (int i = 0; i < arr3.Length; i += 2) {
    var sf = filas.IndexOf(arr3[i]);
    var sc = cols.IndexOf(arr3[i + 1], sf);
    sb.Append(alfa[sc]);
    }

    return sb.ToString();
    }

  9. Paulc said

    Here is another version in Python (a bit more object oriented)

    http://vpaste.net/nksKf?

  10. Christopher said

    A ruby solution

    class String
    def bifid_encipher
    self.gsub!(/[^A-Za-z]/,”)
    stringify coordinates.transpose.flatten.each_slice(2)
    end

    def bifid_decipher
    stringify coordinates.flatten.each_slice(self.size).to_a.transpose
    end

    protected
    def coordinates
    self.upcase.split(//).inject([]) do |a, char|
    polybius_square.each_with_index do |array, i|
    a << [i, $_] if $_ = array =~ /#{char}/
    end

    a
    end
    end

    def stringify(message)
    message.map { |k,v| "%c" % polybius_square[k][v] }.to_s
    end

    def polybius_square
    @square ||= (('A'..'Z').to_a – %w(J)).each_slice(5).map { |a| a.join }
    end
    end

  11. Pete Jones said

    Javascript using a 6×6 square.

    http://pastebin.com/f44f6043c

  12. Kevin Qiu said

    In Clojure:

    (ns bifid
      (:gen-class))
     
     
    (defn polybius-square
      "Polybius square by the given charset and size"
      [charset square-size]
      (map #(vector %1 [%2 %3]) charset
        (for [x (range 1 (+ 1 square-size)), y (range 1 (+ 1 square-size))] x)
        (take (count charset) (cycle (range 1 (+ 1 square-size))))))
     
    (defn- letter-2-code
      "Produce a mapping between letters and their codes"
      [square]
      (letfn [(helper [the-square the-map]
              (if (empty? the-square)
                the-map
                (let [the-item (first the-square)
                      the-key (first the-item)
                      the-number (second the-item)]
                  (recur (rest the-square) (assoc the-map the-key the-number)))))]
        (helper square (empty hash-map))))
     
    (defn- transposed-2-letter
      "Produce a mapping between the transposed codes to letter"
      [square]
      (letfn [(helper [the-square the-map]
                (if (empty? the-square)
                  the-map
                  (let [the-item (first the-square)
                        the-key (second the-item)
                        the-letter (first the-item)]
                    (recur (rest the-square) (assoc the-map the-key the-letter)))))]
        (helper square (empty hash-map))))
     
    (defn encode
      "Return the message encoded by the specified polybius-square"
      [message polybius-square]
      (let [l2c (letter-2-code polybius-square)
            tr2l (transposed-2-letter polybius-square)]
        (apply str
          (map #(get tr2l % %) (partition 2 (apply interleave (map #(get l2c % %) message)))))))
     
    (defn decode
      "Return the decoded message using the specified polybius-square"
      [encoded polybius-square]
      (let [l2c (letter-2-code polybius-square)
            c2l (transposed-2-letter polybius-square)
            codes (apply concat (map #(get l2c % %) encoded))
            len (count codes)
            parts (partition (/ len 2) codes)]
        (apply str (map #(get c2l %1 %1) (map #(vector %1 %2) (first parts) (second parts))))))
     
    (defn -main
      "A simple test case entry point"
      []
      (let [square (polybius-square "ABCDEFGHIKLMNOPQRSTUVWXYZ" 5)]
        (do
            (println (encode "PROGRAMMINGPRAXIS" square))
            (println (decode "OMQNHHQWUIGBIMWCS" square)))))
    
  13. […] best way to learn a language is to use it to solve some non-trivial practical problems. I stumbled this problem on Programming Praxis. It’s about building a Bifid cipher, which I thought could be a […]

  14. DotNetter said

    Another C# soln.

    public class Bifid
    {
    string[,] KeyMatrix = new string[5,5];

    public Bifid()
    {
    BuildKeyMatrix();
    }

    private void BuildKeyMatrix()
    {
    int k = 65;
    for(int i = 0; i <5; i++)
    {
    for(int j = 0; j<5; j++)
    {
    if(k==74) {k++;} // Dont take j (j ascii = 64)
    KeyMatrix[i,j] = ((char)k).ToString();
    k++;
    }
    }
    }

    public string EncryptDecrypt(string Text, bool Encrypt)
    {
    int k = 0;
    string CharofMessage = string.Empty;
    StringBuilder sb1 = new StringBuilder();
    StringBuilder sb2 = new StringBuilder();
    StringBuilder sbOut = new StringBuilder();
    bool HasGotChar = false;

    while(k < Text.Length)
    {
    CharofMessage = Text.Substring(k,1);
    for(int i = 0; i <5; i++)
    {
    for(int j = 0; j<5; j++)
    {
    if(string.Compare(KeyMatrix[i,j],CharofMessage, true) == 0)
    {
    sb1.Append(i.ToString());
    if(Encrypt)
    sb2.Append(j.ToString()); //Use separate string builder for encrypt – ease of coding :-)
    else
    sb1.Append(j.ToString());
    HasGotChar = true;
    break;
    }
    }
    if(HasGotChar) // exit the loop if we hit the character
    {
    HasGotChar = false;
    break;
    }
    }
    k++;
    }

    k = 0;

    if(Encrypt)
    {
    sb1.Append(sb2.ToString()); // combine both
    while(k < sb1.Length)
    {
    sbOut.Append( KeyMatrix[Convert.ToInt32(sb1[k].ToString()),Convert.ToInt32(sb1[k+1].ToString())]);
    k += 2;
    }
    }
    else
    {
    int SplitNum = (sb1.Length) / 2;
    while(k < SplitNum)
    {
    sbOut.Append( KeyMatrix[Convert.ToInt32(sb1[k].ToString()),Convert.ToInt32(sb1[k + SplitNum].ToString())]);
    k ++;
    }
    }

    return sbOut.ToString();
    }
    }

  15. fb said

    My J solution:

    pre=:(]->&9)@-&65@(a.&i.@toupper)
    enc=:|:@((%&2@#,2:)$[)@(<.@%&5,5&|)
    dec=:((2:,%&2@#)$[)@(<.@%&5,@,.5&|)
    pst=:{&a.@(]-<&75)@(5&*@[/+66&+@]/)
    
    encode=:pst@enc@pre
    decode=:pst@dec@pre
    
  16. Rudi Angela said

    Here’s an implementation in Erlang. Source file:
    -module(bifid).
    -export([encode/1, decode/1]).

    encode(Source) ->
    frompoints(makecolumns(flattenrows(topoints(Source)))).

    decode(Source) ->
    frompoints(unflattenrows(flattencolumns(topoints(Source)))).

    % flattenrows(PointsList)
    % flattens a list of two-integer tuples [{X1, Y1}, {X2, Y2} … ]
    % into a list of ints [X1, X2, … Y1, Y2, …]
    flattenrows(Points) ->
    [X || {X,_} <- Points] ++ [Y || {_,Y}
    makepoints(lists:split(length(List) div 2, List), []).

    % makepoints({IntsList1, IntsList2}, AccumulatorList)
    % Helper function for makepoints, that does most of the work
    % Joins corresponding items of the two input lists to two-integer
    % tuples and ads the result to accumulator list
    % at the end the accumulator list is reversed to get the right order
    makepoints({[], _}, Acc) -> lists:reverse(Acc);
    makepoints({[X | Xlist], [Y | Ylist]}, Acc) ->
    makepoints({Xlist, Ylist}, [{X, Y} | Acc]).

    % flattencolumns(PointsList)
    % flattens a list of two-integer tuples [{X1, Y1}, {X2, Y2} … ]
    % into a list of ints [X1, Y1, X2, Y2, …]
    flattencolumns(List) -> flattencolumns(List, []).
    flattencolumns([], Acc) -> lists:reverse(Acc);
    flattencolumns([{X, Y} | Tail], Acc) ->
    flattencolumns(Tail, [Y | [X | Acc]]). % will be reversed

    % makecolumns(IntegersList)
    % does the inverse operation of flattencolumns
    makecolumns(List) -> makecolumns(List, []).

    makecolumns([], Acc) -> lists:reverse(Acc);
    makecolumns([X | [Y | Tail]], Acc) ->
    makecolumns(Tail, [{X, Y} | Acc]).

    % topoints(String, Encoding)
    % calculates the two-integer tuple that represents a character
    % in the given encoding
    topoints(Source, {Key, Period}) ->
    [divrem( indexof(Char, Key), Period) || Char
    frompoints(Source, Key, Period, []).
    frompoints([], _Key, _Period, Accumulator) -> lists:reverse(Accumulator);
    frompoints([{X, Y} | Tail], Key, Period, Accumulator) ->
    Index = (X-1) * Period + (Y),
    Char = lists:nth(Index, Key),
    frompoints(Tail, Key, Period, [Char | Accumulator]);
    frompoints(Any, _, _, Acc) ->
    io:format(“Error: ~p, ~p~n”, [Any, Acc]),
    Acc.

    % divrem(X, Y)
    % function to X div Y and X rem Y and return both as a tuple {Div, Rem}
    % both values are offset by 1 for convenience
    divrem(X, Y) -> divrem(X, Y, 0).
    divrem(X, Y, Acc) when X {Acc+1, X+1};
    divrem(X, Y, Acc) -> divrem(X – Y, Y, Acc + 1).

    % indexof(List, Item)
    % As Erlang has no array data type we have to use linked lists.
    % The lists module does not have a function to calculate the index
    % of an item so here is my implementation.
    indexof(Item, List) -> indexof(Item, List, 0).
    indexof(_Item, [], Start) -> Start;
    indexof(Item, [Head | Tail], Start) ->
    if Item =:= Head -> Start;
    true -> indexof(Item, Tail, Start + 1)
    end.

    % encoding()
    % convenience method for testing
    encoding() -> {“ABCDEFGHIKLMNOPQRSTUVWXYZ”, 5}.

    % topoints(List)
    % convenience method for testing
    topoints(Source) -> topoints(Source, encoding()).

    % frompoints(Source)
    % convenience method for testing
    frompoints(Source) -> frompoints(Source, encoding()).

    In the erlang shell you can then enter:
    1> c(bifid).
    {ok,bifid}
    2> bifid:encode(“PROGRAMMINGPRAXIS”).
    “OMQNHHQWUIGBIMWCS”
    3> E = bifid:encode(“PROGRAMMINGPRAXIS”).
    “OMQNHHQWUIGBIMWCS”
    4> bifid:decode(E).
    “PROGRAMMINGPRAXIS”

  17. Andrey said

    Help me with Visual Basic code for this program….please!!! (

  18. Rohit Phutane said

    package com.rohit.classes;

    import java.util.*;
    import java.util.Map.Entry;

    /**
    * Here is the java solution..:)
    * @author rohitp
    *
    */
    public class BifidCipher {

    public static void main(String[] args) {
    Map cipherMap = new HashMap();
    int count = 0;
    for (int i = 1; i < 6; i++) {
    for (int j = 1; j < 6; j++) {
    char c = (char) (97 + (count++));
    String ij = i + "" + j;
    if (c == 'j') {
    c = (char) (97 + (count++));
    }
    cipherMap.put(c, ij);
    }
    }

    String input = "PROGRAMMINGPRAXIS".toLowerCase();
    StringBuffer strBuff = new StringBuffer();
    for (int i = 0; i < input.length(); i++) {
    char c = input.charAt(i);
    strBuff.append(cipherMap.get(c));
    }
    System.out.println("str:- " + strBuff.toString());
    String str = strBuff.toString();

    StringBuffer newBuff = new StringBuffer();
    for (int i = 0; i < str.length(); i++) {
    if (i % 2 == 0) {
    newBuff.append(str.charAt(i));
    }
    if (i == str.length() – 1) {
    str = str.substring(1, str.length());
    for (int j = 0; j < str.length(); j++) {
    if (j % 2 == 0) {
    newBuff.append(str.charAt(j));
    }
    }
    break;
    }
    }
    String deciText = newBuff.toString();
    String temp = "";
    for (int i = 0; i 0 && i % 2 != 0 && i < deciText.length() – 1) {
    temp += "^";
    }
    }
    String[] deciArr = temp.split("\\^");
    String finalVal = "";
    for (int i = 0; i < deciArr.length; i++) {
    for (Entry entry : cipherMap.entrySet()) {
    if (entry.getValue().equals(deciArr[i])) {
    finalVal += entry.getKey();
    }
    }

    }
    System.out.println(“finalVal:- ” + finalVal);
    }

    }

  19. aruna said

    given the mathematical type not the programming type

  20. Daniel said

    My solution in R. I slightly expanded the key to an eight by eight square in order to include capitals, full stops and spaces.

    encode <- function(message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) ### Create key
    split.message <- strsplit(message,"")[[1]] ### Split message into individual characters

    tr <- vector(length=nchar(message))
    br <- vector(length=nchar(message))

    ### Create empty vectors (top row and bottom row)

    for (i in 1:length(split.message)) {
    tr[i] <- which(poly == split.message[i],arr.ind=T)[1]
    br[i] <- which(poly == split.message[i],arr.ind=T)[2]
    }

    ### This loop looks up the row ([1]) and column ([2]) for each character in the message

    coded.message <- vector(length=nchar(message))

    enc <- c(tr,br) ### Creates a single vector with row and then column numbers for the second step of encoding

    for (i in 1:nchar(message)) {
    coded.message[i] <- poly[enc[2*i-1],enc[2*i]]
    }

    ### This loop reads the numbers in enc in twos, and returns the corresponding letters in the key

    return(paste(coded.message, collapse = ""))

    ### Joins all the characters up into a single string, and returns the coded message!

    }

    decode <- function(coded.message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) #Creates key
    splitcoded.message <- strsplit(coded.message,"")[[1]]

    dec <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    dec[2*i-1] <- which(poly == splitcoded.message[i],arr.ind=T)[1]
    dec[2*i] <- which(poly == splitcoded.message[i],arr.ind=T)[2]
    }

    decoded.message <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    decoded.message[i] encode(“Merry Christmas”)
    [1] “GsFyrsiwHi05cCc”
    > decode(“GsFyrsiwHi05cCc”)
    [1] “Merry Christmas”

  21. Daniel said

    Sloppy copy and pasting technique messed up the end of that. Below is correct code:

    encode <- function(message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) #Creates key
    split.message <- strsplit(message,"")[[1]]

    tr <- vector(length=nchar(message))
    br <- vector(length=nchar(message))

    for (i in 1:length(split.message)) {
    tr[i] <- which(poly == split.message[i],arr.ind=T)[1]
    br[i] <- which(poly == split.message[i],arr.ind=T)[2]
    }

    coded.message <- vector(length=nchar(message))

    enc <- c(tr,br)

    for (i in 1:nchar(message)) {
    coded.message[i] <- poly[enc[2*i-1],enc[2*i]]
    }

    return(paste(coded.message, collapse = ""))
    }

    decode <- function(coded.message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) #Creates key
    splitcoded.message <- strsplit(coded.message,"")[[1]]

    dec <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    dec[2*i-1] <- which(poly == splitcoded.message[i],arr.ind=T)[1]
    dec[2*i] <- which(poly == splitcoded.message[i],arr.ind=T)[2]
    }

    decoded.message <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    decoded.message[i] encode(“Merry Christmas”)
    [1] “GsFyrsiwHi05cCc”
    > decode(“GsFyrsiwHi05cCc”)
    [1] “Merry Christmas”

  22. Daniel said

    Something strange is going on here. Administrators feel free to delete previous comments. One more time….

    encode <- function(message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) #Creates key
    split.message <- strsplit(message,"")[[1]]

    tr <- vector(length=nchar(message))
    br <- vector(length=nchar(message))

    for (i in 1:length(split.message)) {
    tr[i] <- which(poly == split.message[i],arr.ind=T)[1]
    br[i] <- which(poly == split.message[i],arr.ind=T)[2]
    }

    coded.message <- vector(length=nchar(message))

    enc <- c(tr,br)

    for (i in 1:nchar(message)) {
    coded.message[i] <- poly[enc[2*i-1],enc[2*i]]
    }

    return(paste(coded.message, collapse = ""))
    }

    decode <- function(coded.message) {

    poly <- matrix(c(letters,LETTERS,"0","1","2","3","4","5","6","7","8","9"," ","."),nrow=8,byrow=T) #Creates key
    splitcoded.message <- strsplit(coded.message,"")[[1]]

    dec <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    dec[2*i-1] <- which(poly == splitcoded.message[i],arr.ind=T)[1]
    dec[2*i] <- which(poly == splitcoded.message[i],arr.ind=T)[2]
    }

    decoded.message <- vector(length=nchar(coded.message))

    for (i in 1:nchar(coded.message)) {
    decoded.message[i] <- poly[dec[i],dec[i+nchar(coded.message)]]
    }

    return(paste(decoded.message, collapse = ""))
    }

Leave a comment