Re: How to program an enigma cipher?




DarkProtoman wrote:
mensanator@xxxxxxx wrote:
DarkProtoman wrote:
How would I program an enigma cipher that can encipher A-Z and 0-9?

Use base 36. But in base 36, it's 0123456789abcdefghijklmnopqrtuvwxyz.


I'm thinking this: since the enigma cipher is basically a vigenere
cipher w/ a shifting table, and a vigenere encryption can be written as
(P+K)%36 ('cause there's 36 characters to work w/), and let's say
there's 4 rotors (let's remove the reflector and plugboard to keep it
simple), we could do it like this, encrypting F for an example:

R1=Q, R2=W,R3=E,R4=R

R1 alphabet: QRSTUVWXYZ0123456789ABCDEFGHIJKLMNOP

F becomes V, R1 moves to R.

Unless it's base 36, in which case 'f' becomes '6'.


R2 alphabet: WXYZ0123456789ABCDEFGHIJKLMNOPQRSTUV

V becomes H

R2 doesn't move (it'll only move after R1 has moved 36 characters)

R3 alphabet: EFGHIJKLMNOPQRSTUVWXYZ0123456789

H becomes L

R3 doesn't move (it'll only move after R2 has moved 36 characters)

R4 alphabet: RSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQ

L becomes 2.

Thus, F->2.

I know this is imperfect, so any comments or suggestions on how to do
this are most welcome!

Thanks!!!

Python:

import gmpy

def init_rotor(R,i): # set rotor to start at position i
ii = int(i,36) # convert base 36 char to integer
while R[0] != ii:
p = R.pop(0) # .pop(0) .append() moves first list item
R.append(p) # to last, effectively rotating one position

def print_rotors():
for i in R1:
print '%2s' % (gmpy.digits(i,36)),
print
for i in R2:
print '%2s' % (gmpy.digits(i,36)),
print
for i in R3:
print '%2s' % (gmpy.digits(i,36)),
print
for i in R4:
print '%2s' % (gmpy.digits(i,36)),
print

def spin_rotors():
global R1cnt, R2cnt, R3cnt
p = R1.pop(0) # rotate R1
R1.append(p)
R1cnt = (R1cnt + 1) % 36 # increment rotation count
if R1cnt == 0: # if rollover...
p = R2.pop(0) # ...rotate R2
R2.append(p)
R2cnt = (R2cnt + 1) % 36
if R2cnt == 0: # if rollover...
p = R3.pop(0) # ...rotate R3
R3.append(p)
R3cnt = (R3cnt + 1) % 36
if R3cnt == 0: # if rollover...
p = R4.pop(0) # ...rotate R4
R4.append(p)

def encode(a):
aa = int(a,36) # convert base 36 char to integer
i = R1[aa] # R1 is index to R2
j = R2[i] # R2 is index to R3
k = R3[j] # R3 is index to R4
m = R4[k] # R4 is the encoded value
s = gmpy.digits(m,36) # convert to base 36 char
spin_rotors()
return s

def decode(a):
aa = int(a,36) # reverse encoding process
i = R4.index(aa)
j = R3.index(i)
k = R2.index(j)
m = R1.index(k)
s = gmpy.digits(m,36)
spin_rotors()
return s

base36 = '0123456789abcdefghijklmnopqrstuvwxyz'

R1 = [i for i in xrange(36)] # create the rotors
R2 = R1[:]
R3 = R1[:]
R4 = R1[:]

init_rotor(R1,'q') # set rotors to starting points
init_rotor(R2,'w')
init_rotor(R3,'e')
init_rotor(R4,'r')

R1cnt = 0 # reset rotor counts
R2cnt = 0
R3cnt = 0

plain = """
four score and seven years ago
our fathers brought forth on this
continent a new nation conceived
in liberty and dedicated to the
proposition that all men are
created equal.
"""

print
print 'Plain text:'
print plain

enigma = ''

for c in plain:
if c in base36: # anything NOT a base 36 character
enigma = enigma + encode(c)
else: # leave as is
enigma = enigma + c

print
print 'Encoded:'
print enigma

init_rotor(R1,'q') # set rotors to starting points
init_rotor(R2,'w')
init_rotor(R3,'e')
init_rotor(R4,'r')

R1cnt = 0 # reset rotor counts
R2cnt = 0
R3cnt = 0

plain = ''

for c in enigma:
if c in base36:
plain = plain + decode(c)
else:
plain = plain + c

print
print 'Decoded:'
print plain

##
## Plain text:
##
## four score and seven years ago
## our fathers brought forth on this
## continent a new nation conceived
## in liberty and dedicated to the
## proposition that all men are
## created equal.
##
##
## Encoded:
##
## 6gnl n8lpd aof vi0ku 6nk24 nu3
## 4b9 yue31fh 1jhobdq dnruj rr ynp0
## lyy5v1t3a s 6yh 9xh7ee 5ii8bguee
## kq pnhlz28 lzq rttzutdzz gc i75
## hljllqhtjqq xmg0 iuv xq0 o6u
## t9xue00 2fk1d.
##
##
## Decoded:
##
## four score and seven years ago
## our fathers brought forth on this
## continent a new nation conceived
## in liberty and dedicated to the
## proposition that all men are
## created equal.
##

First off. I program in C++.

Which you didn't mention.

So just look at the algorithm and do the same thing in C++.
The GMP library supports C++.

And doesn't C++ have something equivalent to a list?
If not, how hard is it to use an array and create .pop &
..append methods? Or just use a pointer to show where
the rotor is currently positioned.

Second, the rotor and reflector positions
need to be user settable.

How hard is it to call init_rotor() with user selected starting
positions?

Third, there's five rotors and a reflector.

You said four in the post I replied to.

How hard would it be to add another rotor?

You didn't mention any reflector. What does it do and
how hard would it be to implement?

.



Relevant Pages

  • Re: How to program an enigma cipher?
    ... since the enigma cipher is basically a vigenere ... R1 alphabet: QRSTUVWXYZ0123456789ABCDEFGHIJKLMNOP ... def print_rotors: ... print 'Plain text:' ...
    (comp.programming)
  • Re: How to program an enigma cipher?
    ... since the enigma cipher is basically a vigenere ... R1 alphabet: QRSTUVWXYZ0123456789ABCDEFGHIJKLMNOP ... def print_rotors: ... print 'Plain text:' ...
    (comp.programming)
  • Re: How to program an enigma cipher?
    ... since the enigma cipher is basically a vigenere ... def print_rotors: ... print 'Plain text:' ... the rotor is currently positioned. ...
    (comp.programming)
  • Re: How to program an enigma cipher?
    ... since the enigma cipher is basically a vigenere ... def print_rotors: ... print 'Plain text:' ... the rotor is currently positioned. ...
    (comp.programming)