Conversión entre minúsculas y mayúsculas a nivel de bits

ascii_ansi.gif

Nunca me había percatado de esta curiosidad en la codificación de los caracteres en ASCII. Cómo ya todos sabemos, cada carácter en ASCII tiene su propio código, incluido las letras mayúsculas y minúsculas. Por ejemplo, la letra A = 65 y la a = 97, en decimal.

Si cogemos todos los caracteres en mayúsculas (A-Z) y todos los minúsculas (a-z) e imprimimos su código en binario, observamos que todos los bits son iguales, excepto el sexto bit (contando desde la derecha):

('a'..'z').each {|c| puts "#{c} = #{c.ord.to_s(2)}"} # ruby

a = 1100001 b = 1100010 c = 1100011 d = 1100100 e = 1100101 f = 1100110 g = 1100111 h = 1101000 i = 1101001 j = 1101010 k = 1101011 l = 1101100 m = 1101101 n = 1101110 o = 1101111 p = 1110000 q = 1110001 r = 1110010 s = 1110011 t = 1110100 u = 1110101 v = 1110110 w = 1110111 x = 1111000 y = 1111001 z = 1111010

('A'..'Z').each {|c| puts "#{c} = #{c.ord.to_s(2)}"} # ruby

A = 1000001 B = 1000010 C = 1000011 D = 1000100 E = 1000101 F = 1000110 G = 1000111 H = 1001000 I = 1001001 J = 1001010 K = 1001011 L = 1001100 M = 1001101 N = 1001110 O = 1001111 P = 1010000 Q = 1010001 R = 1010010 S = 1010011 T = 1010100 U = 1010101 V = 1010110 W = 1010111 X = 1011000 Y = 1011001 Z = 1011010

Las minúsculas tienen el sexto bit a 1 y las mayúsculas a 0. Por lo tanto cambiando dicho de bit de 1 a 0 ó 1 a 0, podemos convertir entre mayúsculas o minúsculas. Haciendo un XOR de un carácter con el carácter espacio cuyo código es el 32 en decimal, por lo tanto 100000 en binario podemos hacer la conversión, ya que esta operación invertirá el bit 6. Un ejemplo en ruby:

1.9.3p286 :091 > ('A'.ord ^ ' '.ord).chr
=> "a"

1.9.3p286 :092 > ('b'.ord ^ ' '.ord).chr
=> "B"

Fuente