Recipe 1.4. Converting Between ASCII Characters and Values
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:28:49Z

#

| Chapter 1 Strings |

## 1.4. Converting Between ASCII Characters and Values

### Problem

You want to print out the number represented by a given ASCII character, or you want to print out an ASCII character given a number.

### Solution

Use `ord` to convert a character to a number, or use `chr` to convert a number to a character:

    $num  = ord($char);
    $char = chr($num);

The `%c` format used in `printf` and `sprintf` also converts a number to a character:

    $char = sprintf("%c", $num);                # slower than chr($num)
    printf("Number %d is character %c\n", $num, $num);
    Number 101 is character e

A `C*` template used with `pack` and `unpack` can quickly convert many characters.

    @ASCII = unpack("C*", $string);
    $STRING = pack("C*", @ascii);

### Discussion

Unlike low-level, typeless languages like assembler, Perl doesn't treat characters and numbers interchangeably; it treats strings and numbers interchangeably. That means you can't just assign characters and numbers back and forth. Perl provides Pascal's `chr` and `ord` to convert between a character and its corresponding ordinal value:

    $ascii_value = ord("e");    # now 101
    $character   = chr(101);    # now "e"

If you already have a character, it's really represented as a string of length one, so just print it out directly using `print` or the `%s` format in `printf` and `sprintf`. The `%c` format forces `printf` or `sprintf` to convert a number into a character; it's not used for printing a character that's already in character format (that is, a string).

    printf("Number %d is character %c\n", 101, 101);

The `pack`, `unpack`, `chr`, and `ord` functions are all faster than `sprintf`. Here are `pack` and `unpack` in action:

    @ascii_character_numbers = unpack("C*", "sample");
    print "@ascii_character_numbers\n";
    115 97 109 112 108 101

    $word = pack("C*", @ascii_character_numbers);
    $word = pack("C*", 115, 97, 109, 112, 108, 101);   # same
    print "$word\n";
    sample

Here's how to convert from HAL to IBM:

    $hal = "HAL";
    @ascii = unpack("C*", $hal);
    foreach $val (@ascii) {
        $val++;                 # add one to each ASCII value
    }
    $ibm = pack("C*", @ascii);
    print "$ibm\n";             # prints "IBM"

The `ord` function can return numbers from 0 to 255. These correspond to C's `unsigned` `char` data type.

### See Also

The `chr`, `ord`, `printf`, `sprintf`, `pack`, and `unpack` functions in perlfunc (1) and Chapter 3 of Programming Perl

1.3. Exchanging Values Without Using Temporary Variables |  | 1.5. Processing a String One Character at a Time