使用 ASCII 表有一个小技巧。大写和小写字符仅相差一位。所以你可以一次处理它们。看看这个:
A = 0100 0001 M = 0100 1101
a = 0110 0001 m = 0110 1101
所以,我认为这应该有效:
if (Character.isLetter(c))
return (char) ((((c & 0b01011111) - 'A' + 13) % 26 + 'A') | (c & 0b00100000));
return c;
解释:
c & 0b01011111
把 char 变成大写。
- 'A' + 13
转换为基于 0 的 int 并应用偏移量。
% 26 + 'A'
取模并使其返回一个字符。
(c & 0b00100000)
获取指示 char 是否为小写的位。
|
将该位添加回结果以使其小写(如果是)。
您可以在此处使用条件运算符使其成为单行符:
return Character.isLetter(c) ? (char) ((((c & 0b01011111) - 'A' + 13) % 26 + 'A') | (c & 0b00100000)) : c;
用十进制 int 文字替换 binary 和 char 文字后,您会得到:
return Character.isLetter(c) ? (char) ((((c & 95) - 52) % 26 + 65) | (c & 32)) : c;
消除空格和一些额外的括号给出:(65个字符)
return Character.isLetter(c)?(char)((((c&95)-52)%26+65)|c&32):c;
恕我直言,如果涉及打高尔夫球,这是一场胜利。这当然是不可读的。
演示:是的,已确认。它有效:http: //ideone.com/l6xYy6
输出摘录:
= -> =
> -> >
? -> ?
@ -> @
A -> N
B -> O
C -> P
D -> Q
更进一步:
W -> J
X -> K
Y -> L
Z -> M
[ -> [
\ -> \
] -> ]
^ -> ^
_ -> _
` -> `
a -> n
b -> o
c -> p
d -> q