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)
@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