Toggle Shift Key
JavaScript (Node.js), 110 ... 97 96 bytes
c=>(s=")0@2^6&7*8(9\"'+=-_:;`~")[s.indexOf(c)^1]||(B=Buffer)([([n]=B(c),n%127>32)<<4+n/64^n])+''
Try it online!
How?
We use a lookup table for these pairs:
) ↔️ 0
@ ↔️ 2
^ ↔️ 6
& ↔️ 7
* ↔️ 8
( ↔️ 9
" ↔️ '
+ ↔️ =
- ↔️ _
: ↔️ ;
` ↔️ ~
For all other characters, we use the following code:
(B = Buffer)([ // generate a buffer from a singleton array:
( //
[n] = B(c), // n = ASCII code of the input character
n % 127 > 32 // 1 if 32 < n < 127, or 0 otherwise
) //
<< 4 + n / 64 // left-shifted by 4 if n < 64, or by 5 otherwise
^ n // XOR'ed with n
]) + '' // end of Buffer(); coerce it to a string
which supports these 3 cases:
If \$32<n<64\$, we XOR the ASCII code with \$16\$, which is what we need for:
! ↔️ 1 # ↔️ 3 $ ↔️ 4 % ↔️ 5 , ↔️ < . ↔️ > / ↔️ ?
If \$64\le n<127\$, we XOR the ASCII code with \$32\$, which toggles the case of letters and also works for these pairs:
[ ↔️ { \ ↔️ | ] ↔️ }
If \$n\le32\$ or \$n=127\$, the character is left unchanged (ASCII code XOR'ed with \$0\$).
x86-16, Genuine IBM PC, 32 31 29 bytes
00000000: b4f0 8ec0 bfe5 e8b3 3ab1 74a0 8200 f2ae ........:.t.....
00000010: 3acb 7f02 f7db 268a 41ff cd29 c3 :.....&.A..).
Build with xxd -r
.
Unassembled listing:
B4 F0 MOV AH, 0F0H ; BIOS segment address (F000H)
8E C0 MOV ES, AX ; set ES to BIOS segment for SCASB
BF E8E5 MOV DI, E8E5H ; set to LABEL K10
B3 3A MOV BL, 58 ; size of table
B1 74 MOV CL, 58*2 ; size of both tables
A0 0082 MOV AL, BYTE PTR DS:[82H] ; get input char from command line
F2/ AE REPNZ SCASB ; search BIOS table for char
3A CB CMP CL, BL ; found in the lowercase table?
7F 02 JG UPPER ; if so, convert with uppercase table by adding
F7 DB NEG BX ; otherwise subtract the offset
UPPER:
26:8A 41 FF MOV AL, ES:[BX+DI-1] ; get char from table
CD 29 INT 29H ; DOS fast write to console
C3 RET ; return to DOS
Input/Output:
How does it work?
Well, the PC BIOS already contains all of the code and tables necessary for this since it actually handles the conversion of scan codes received from the keyboard to ASCII chars (in real/DOS mode at least). There's no way (that I know of) to actually hook this on just any "PC-compatible" BIOS, however if you know the location of the table in ROM (on the IBM PC it starts at F000:E8E5
), you can use that.
On Page A-25 of Appendix A the IBM PC Technical Reference (listing of the entire source code of the PC BIOS) is the disassembly of this table:
Unfortunately, this address will be different on any given PC-clone BIOS and of course, there's no guarantee that it would even be implemented in the same way by anyone else. Thus, this submission is guaranteed to run only on a Genuine IBM PC. Go Big Blue!
Retina 0.8.2, 34 bytes
T`-~A-]d';-?/.+,:"(*&^%$#@!)}-_`Ro
Try it online! Link includes test cases.
Explanation: The T
command is Retina's transliteration operation. Among its special characters are:
`
: Delimit the parts of the command-
: Introduce a range (this suppresses the following special characters sod-o
just meansdefghijklmno
)_
: Delete the matching characterd
:0-9
R
: Reverse the next rangeo
: Take the source string as the range
The trick is therefore to create as many ranges as possible to reduce the length, plus avoiding having the -
and _
characters where they would be interpreted as a special character and avoiding the `
at all by including it inside a range. Additionally arranging for the range to transliterate to its reversal allows that to be expressed very cheaply.