Cipher

Discussion in 'Ruby' started by Max Zhou, Mar 17, 2008.

1. Max ZhouGuest

[Note: parts of this message were removed to make it a legal post.]

I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.
abcdefghijklm
nopqrstuvwxyz

---------------------------------
Never miss a thing. Make Yahoo your homepage.

Max Zhou, Mar 17, 2008

2. Thomas WieczorekGuest

On Mon, Mar 17, 2008 at 1:50 AM, Max Zhou <> wrote:
> I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.
> abcdefghijklm
> nopqrstuvwxyz
>

You can split a string with the String#split method:
irb
> "Foobar".split(//)

=> ["F", "o", "o", "b", "a", "r"]

You can get the ASCII value of a character either with ?character:
> ?F

=> 70

If you want to loop the splitted string, try eval(has anyone a better
solution?):
> "Foobar".split(//).each { |c| puts eval("?#{c}") }

You can use Fixnum#chr to turn an ASCII value in a character:
> 65.chr #=> "A"

You're trying to implement the ROT13 or ROTx algorithm. A naive
approach, still buggy might look like that:
plaintext = "Hello"
encrypted = ""
plaintext.split(//).each { |c| i=eval("?#{c}"); encrypted << (i+13).chr }
puts encrypted #=> Uryy|

As you see, the encrypted string contains a |(vertical line) and it
also chokes on spaces. I leave the rest to you. Ask again if you're
stuck.

Regards, Thomas

Thomas Wieczorek, Mar 17, 2008

3. Todd BensonGuest

On Sun, Mar 16, 2008 at 7:50 PM, Max Zhou <> wrote:
> I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.
> abcdefghijklm
> nopqrstuvwxyz
>
>
>
> ---------------------------------
> Never miss a thing. Make Yahoo your homepage.

There are many ways to do it, but if it was all lower case, I would probably...

a = "abcdefghijklmnopqrstuvwxyz"
ascii_offset = 15 - 97
str = "antidisestablishmentarianism"
str.each_byte {|b| new_str << a[(b + ascii_offset) % a.size]}
puts new_str

The 15 is to turn a into a p (?p - ?a == 15). The minus 97 part is to
make sure we work in the ascii byte code range. each_byte runs
through each byte of the string, where, in the block, the offset is
added and the mod by the size of a (26) to keep the index of a within
the correct bounds. a[] selects a byte to be appended (<<) to
new_str.

You could wrap this in a method or make it part of String class.
Ideally, I think a person would really want to include the full 256
character set to deal with punctuation and spaces.

Todd

Todd Benson, Mar 17, 2008
4. Todd BensonGuest

On Sun, Mar 16, 2008 at 9:00 PM, Todd Benson <> wrote:
>
> On Sun, Mar 16, 2008 at 7:50 PM, Max Zhou <> wrote:
> > I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.

Also, I forgot to mention that you should realize that a String object
should be thought of as really just an ordering of bytes with some
special methods to make it human readable.

Todd

Todd Benson, Mar 17, 2008
5. Todd BensonGuest

On Sun, Mar 16, 2008 at 9:00 PM, Todd Benson <> wrote:
>
> On Sun, Mar 16, 2008 at 7:50 PM, Max Zhou <> wrote:
> > I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.
> > abcdefghijklm
> > nopqrstuvwxyz
> >
> >
> >
> > ---------------------------------

Just for fun, I revisited this. To include the printable characters
on an english-based system (ASCII codes 32 through 126), not including
tab, return, line-feed, etc...

puts str = "Hello, world! Yabba dabba doo!"
puts

char_set = (32..126).map.pack('c*')
start, finish, offset = ?a, ?p, ?p - ?a
puts "char_set:\n" + char_set = (?\s..?~).map.pack('c*')
puts

size = char_set.size
new_str = ""
str.each_byte do |byte|
new_str << char_set[(byte + offset - char_set[0]) % size]
end
puts "enciphered: \n" + new_str

Todd

Todd Benson, Mar 17, 2008
6. Todd BensonGuest

On Mon, Mar 17, 2008 at 5:21 AM, Todd Benson <> wrote:
> On Sun, Mar 16, 2008 at 9:00 PM, Todd Benson <> wrote:
> >

>
> > On Sun, Mar 16, 2008 at 7:50 PM, Max Zhou <> wrote:
> > > I am trying to make a program that takes what you input, and encrypts it by turning a to p, b to q, z to b, etc. It moves the letter 2 spaces to the left (a to c) and moves it down (c to p). (See below.) Even though you can just say that a will be n, how do you seperate each letter and turn it into a string? Please put it in terms that a Ruby beginner would understand.
> > > abcdefghijklm
> > > nopqrstuvwxyz
> > >
> > >
> > >
> > > ---------------------------------

>
> Just for fun, I revisited this. To include the printable characters
> on an english-based system (ASCII codes 32 through 126), not including
> tab, return, line-feed, etc...
>
>
> puts str = "Hello, world! Yabba dabba doo!"
> puts
>
> char_set = (32..126).map.pack('c*')
> start, finish, offset = ?a, ?p, ?p - ?a
> puts "char_set:\n" + char_set = (?\s..?~).map.pack('c*')
> puts
>
> size = char_set.size
> new_str = ""
> str.each_byte do |byte|
> new_str << char_set[(byte + offset - char_set[0]) % size]
> end
> puts "enciphered: \n" + new_str

Dang it! Another thing that unit tests won't catch: code that is
redundant! Removing the first "char_set =" line will have the same
result...

puts str = "Hello, world! Yabba dabba doo!"
puts

start, finish, offset = ?a, ?p, ?p - ?a
puts "char_set:\n" + char_set = (?\s..?~).map.pack('c*')
puts

size = char_set.size
new_str = ""
str.each_byte do |byte|
new_str << char_set[(byte + offset - char_set[0]) % size]
end
puts "enciphered: \n" + new_str

Todd

Todd Benson, Mar 17, 2008
7. Todd BensonGuest

On Sun, Mar 16, 2008 at 9:00 PM, Todd Benson <> wrote:

> a = "abcdefghijklmnopqrstuvwxyz"
> ascii_offset = 15 - 97

new_str = ""
> str = "antidisestablishmentarianism"
> str.each_byte {|b| new_str << a[(b + ascii_offset) % a.size]}
> puts new_str

I think I'm going to drop google mail; that, or come up with a more
clear way to cut and paste :/

Todd

Todd Benson, Mar 17, 2008