Simple Skript Codierung

Hello,
I am trying to learn ruby and wanted to try a simple script from a book. unfortunately this does not work.

puts "Text:"
text = gets.chomp
print "Schlüssel (1..255):"
key = gets.to_i

#Fehlermeldung und Ende bei unnzulässigen Schlüssel
if key < 1 or key > 255
  puts "Ungueltiger Key"
  exit
end

# Verschluesselter Text ist zuuerst Leer
encrypt = ''

# For-Schleife ueber alle Zeichjen des Texts
for i in 0...text.length
  puts text[i]
  #durch Exclusives oder markirten Zeichencode wieder in Zeichen umwandeln
  encrypt += ((text[i]^key).chr)
end
print "Verschlüsselter Text: #{encrypt}"

The “undefined method `^’ for “s”:String” error

The issue is that the code is invoking the XOR operator ^ on a string character text[i]

The XOR operator can only be invoked on numbers, not strings, so you would have to convert the string character into a number first by calling the ord method.

text[i].ord^key

Here is the full code, corrected:

puts "Text:"
text = gets.chomp
print "Schlüssel (1..255):"
key = gets.to_i

#Fehlermeldung und Ende bei unnzulässigen Schlüssel
if key < 1 or key > 255
  puts "Ungueltiger Key"
  exit
end

# Verschluesselter Text ist zuuerst Leer
encrypt = ''

# For-Schleife ueber alle Zeichjen des Texts
for i in 0...text.length
  puts text[i]
  #durch Exclusives oder markirten Zeichencode wieder in Zeichen umwandeln
  encrypt += ((text[i].ord^key).chr)
end
print "Verschlüsselter Text: #{encrypt}"

Here is the output I got for 'hello' and 5:

Verschlüsselter Text: m`iij

One last thing to note is that it is not idiomatic in Ruby to use the for loop since it is much simpler to use each instead among multiple alternatives.

Here is the code rewritten with idiomatic Ruby by using each on a Range:

puts "Text:"
text = gets.chomp
print "Schlüssel (1..255):"
key = gets.to_i

#Fehlermeldung und Ende bei unnzulässigen Schlüssel
if key < 1 or key > 255
  puts "Ungueltiger Key"
  exit
end

# Verschluesselter Text ist zuuerst Leer
encrypt = ''

# For-Schleife ueber alle Zeichjen des Texts
(0...text.length).each do |i|
  puts text[i]
  #durch Exclusives oder markirten Zeichencode wieder in Zeichen umwandeln
  encrypt += ((text[i].ord^key).chr)
end
print "Verschlüsselter Text: #{encrypt}"

Here is another version using each on string characters (shorter):

puts "Text:"
text = gets.chomp
print "Schlüssel (1..255):"
key = gets.to_i

#Fehlermeldung und Ende bei unnzulässigen Schlüssel
if key < 1 or key > 255
  puts "Ungueltiger Key"
  exit
end

# Verschluesselter Text ist zuuerst Leer
encrypt = ''

# For-Schleife ueber alle Zeichjen des Texts
text.chars.each do |char|
  puts char
  #durch Exclusives oder markirten Zeichencode wieder in Zeichen umwandeln
  encrypt += ((char.ord^key).chr)
end
print "Verschlüsselter Text: #{encrypt}"

Cheers and welcome to Ruby!

Thanks for the help. Then this must be a mistake in the book. I wanted to test the code myself, I was aware of what it was doing but I didn’t know of any other method that could have done it.