17

I want to convert a single character of a string into an integer, add 2 to it, and then convert it back to a string. Hence, A becomes C, K becomes M, etc.

as2d3
  • 802
  • 2
  • 10
  • 27
Luke
  • 558
  • 1
  • 5
  • 24

8 Answers8

24

This is done through the chr and ord functions. Eg; chr(ord(ch)+2) does what you want. These are fully described here.

Nikwin
  • 6,576
  • 4
  • 35
  • 43
16

This sounds a lot like homework, so I'll give you a couple of pieces and let you fill in the rest.

To access a single character of string s, its s[x] where x is an integer index. Indices start at 0.

To get the integer value of a character it is ord(c) where c is the character. To cast an integer back to a character it is chr(x). Be careful of letters close to the end of the alphabet!

Edit: if you have trouble coming up with what to do for Y and Z, leave a comment and I'll give a hint.

danben
  • 80,905
  • 18
  • 123
  • 145
  • 2
    +1 for good homework guidance without giving away the solution – Kena Dec 17 '09 at 16:53
  • Yeah, I was afraid that someone was going to think it was homework. I already have a B.S. in Computer Science, and I'm an ASP.NET programmer. But I've been picking up Django and wanted to sharpen my Python skills using this site: http://www.pythonchallenge.com/pc/def/map.html. Anyways, I think that 'ord' is the function I was looking for; I'll give it a shot after work. Thanks for everyone's input! – Luke Dec 18 '09 at 00:15
  • 1
    Ah, ok. My two cents on making stuff not sound like homework, if you're so inclined: only post the part of the problem you want answered (like "how do I convert a character to an int in python" rather than the full question which I actually remember as being one of the first questions in my cryptography class in school) and also, I think just saying "This might sound like homework, but it's not" will get us all to remove the condescension from our responses :) That looks like a cool site though, I'll have to check it out. – danben Dec 18 '09 at 03:40
4

Normally, Just ord and add 2 and chr back, (Y, Z will give you unexpected result ("[","\")

>>> chr(ord("A")+2)
'C'

If you want to change Y, Z to A, B, you could do like this.

>>> chr((ord("A")-0x41+2)%26+0x41)
'C'
>>> chr((ord("Y")-0x41+2)%26+0x41)
'A'
>>> chr((ord("Z")-0x41+2)%26+0x41)
'B'

Here is A to Z

>>> [chr((i-0x41+2)%26+0x41) for i in range(0x41,0x41+26)]
['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B']
YOU
  • 120,166
  • 34
  • 186
  • 219
3

http://docs.python.org/library/functions.html

ord(c)

Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object, or the value of the byte when the argument is an 8-bit string. For example, ord('a') returns the integer 97, ord(u'\u2020') returns 8224. This is the inverse of chr() for 8-bit strings and of unichr() for unicode objects. If a unicode argument is given and Python was built with UCS2 Unicode, then the character’s code point must be in the range [0..65535] inclusive; otherwise the string length is two, and a TypeError will be raised.

Jorenko
  • 2,594
  • 2
  • 21
  • 26
2

"ord" is only part of the solution. The puzzle you mentioned there rotates, so that "X"+3 rotates to "A". The most famous of these is rot-13, which rotates 13 characters. Applying rot-13 twice (rotating 26 characters) brings the text back to itself.

The easiest way to handle this is with a translation table.

import string

def rotate(letters, n):
    return letters[n:] + letters[:n]

from_letters = string.ascii_lowercase + string.ascii_uppercase
to_letters = rotate(string.ascii_lowercase, 2) + rotate(string.ascii_uppercase, 2)

translation_table = string.maketrans(from_letters, to_letters)

message = "g fmnc wms bgblr"
print message.translate(translation_table)

Not a single ord() or chr() in here. That's because I'm answering a different question than what was asked. ;)

Andrew Dalke
  • 14,889
  • 4
  • 39
  • 54
  • @dalke already knows this, but for those who don't, an even simpler way to do the above for rot-13 specifically is message.decode('rot13'). (The above is rot-n.) – Peter Hansen Dec 19 '09 at 10:57
1

Try ord(), should do the trick :)

James
  • 24,676
  • 13
  • 84
  • 130
0

For a whole string this would be:

>>> s = "Anne"
>>> ''.join([chr(ord(i)+2) for i in s]) 
'Cppg'

It's diffucult for 'Y', 'Z' ...

>>> s = "Zappa"
>>> ''.join([chr(ord(i)+2) for i in s]) 
'\\crrc'

Functions: chr, ord

miku
  • 181,842
  • 47
  • 306
  • 310
0

For those who need to perform the operation on each character of the string, another way of handling this is by converting the str object to/from a bytes object which will take advantage of the fact that a bytes object is just a sequence of integers.

import numpy


old_text_str = "abcde"  # Original text
old_num_list = list(old_text_str.encode())  # Integer values of the original text
new_num_list = numpy.add(old_num_list, 2).tolist()  # Add +2 to the integer values
new_text_str = bytes(new_num_list).decode()  # Updated text

print(f"{old_text_str=}")
print(f"{old_num_list=}")
print(f"{new_num_list=}")
print(f"{new_text_str=}")

Output:

old_text_str='abcde'
old_num_list=[97, 98, 99, 100, 101]
new_num_list=[99, 100, 101, 102, 103]
new_text_str='cdefg'

Related topics: