Skip to content

Instantly share code, notes, and snippets.

@rwoeber
Created January 11, 2010 10:09
Show Gist options
  • Save rwoeber/274126 to your computer and use it in GitHub Desktop.
Save rwoeber/274126 to your computer and use it in GitHub Desktop.
Ruby rot13
# or simply:
'foobar'.tr 'A-Za-z','N-ZA-Mn-za-m'
# rot(x)
class String
def rot(num = 13)
return self.split("").collect { |ch|
if /^[a-z]$/ === ch
((ch[0] + num - 'a'[0]) % 26 + 'a'[0]).chr
elsif /^[A-Z]$/ === ch
((ch[0] + num - 'A'[0]) % 26 + 'A'[0]).chr
else
ch
end
}.join("")
end
alias rot13 rot
end
p "foobar".rot(2)
@webmstk
Copy link

webmstk commented May 15, 2016

class String
  def rot13
    split('').inject('') do |text, char|
      text << case char
        when 'a'..'m', 'A'..'M'
          char.ord + 13
        when 'n'..'z', 'N'..'Z'
          char.ord - 13
        else
          char.ord
      end
    end
  end
end

@gianniballerini
Copy link

gianniballerini commented Sep 6, 2016

# same thing but let's you choose your rot number
def rot(string, num)
  if num > 25
    num = num - (25 *(num/25))
  end
  new_UpFirst = (65 + num).chr
  new_UpLast = (65 + num - 1).chr
  new_DwnFirst = (97 + num).chr
  new_DwnLast = (97 + num - 1).chr
  case num
  when 0
    puts string
  when 1
    puts string.tr "A-Za-z", "#{new_UpFirst}-ZA#{new_DwnFirst}-za"
  when 25
    puts string.tr "A-Za-z", "ZA-#{new_UpLast}za-#{new_DwnLast}"
  else
    puts string.tr "A-Za-z", "#{new_UpFirst}-ZA-#{new_UpLast}#{new_DwnFirst}-za-#{new_DwnLast}"
  end
end

@svoop
Copy link

svoop commented Oct 23, 2016

Rot by anything:

class String
  def rot(shift=13)
    tr "A-Za-z", "#{(65 + shift).chr}-ZA-#{(64 + shift).chr}#{(97 + shift).chr}-za-#{(96 + shift).chr}"
  end
end

@xfaider
Copy link

xfaider commented Jun 6, 2017

def rot13(string)
string.tr("A-Za-z", "N-ZA-Mn-za-m")
end

@zhisme
Copy link

zhisme commented Nov 3, 2017

def rot13(string)
  string.chars.map do |c| 
    if c.ord.between?('A'.ord, 'M'.ord) || c.ord.between?('a'.ord, 'm'.ord)
      c.ord + 13
    elsif c.ord.between?('n'.ord, 'z'.ord) || c.ord.between?('N'.ord, 'Z'.ord)
      c.ord - 13
    else 
      c.ord
    end
  end.map(&:chr).join
end

I think this one is more readable.

@batter
Copy link

batter commented Feb 11, 2019

@xfaider, nice simple answer

@Kawsay
Copy link

Kawsay commented Jun 13, 2020

Rot by anything:

class String
  def rot(shift=13)
    tr "A-Za-z", "#{(65 + shift).chr}-ZA-#{(64 + shift).chr}#{(97 + shift).chr}-za-#{(96 + shift).chr}"
  end
end

"abc".rot(1) #=> "Abc"

@xfaider approach is simple and elegant. I think this should work for a flexible approach:

def rot(string, amount)
  pivot = ('a'.ord + amount)
  string.tr('a-z', "#{(pivot - 1).chr}-za-#{pivot.chr}")
end

# not working
# rot("b", 25) == rot("b", 24)

if you want amount to be higher than 26:

amount = (amount % 26 + 1) if amount >= 26

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment