[Question]
  [
# The challenge
Make 2 programs which convert decimal to and from base 94, or a bidirectional program.
# Base 94?
Base 94 is like any other base, but instead of 0 to 9 and letters, it uses ASCII characters 33 to 126. Not 127 because `chr(127)` is DEL. Not 32 because that's a *space*.
# Examples
```
0 - ! or empty string
1 - "
93 - ~
94 - "!
2020 - 6O
14233221 - 2-n8
```
# Scoring
For two programs, the score will be the sum of the byte count of both of the programs.
The bidirectional program is simply just the byte count. Consider it like a -50% to the score.
  
[Answer]
# [Haskell](https://www.haskell.org/), 42 + 31 = 73 bytes
**To base 94: 42 bytes**
```
(l!!)
l="":tail[s++[c]|s<-l,c<-['!'..'~']]
```
[Try it online!](https://tio.run/##FcixDsIgEADQ3a84GhM0haY9utiUL0EGQkSJ14ZIx8ZP99ThLe8R6vNGxMle@URCnA9km2baQiZX29ZFv9dZk4qzdlLIrpNv6T0vIa9gobzyusERllAggesVDAou5mdUgD3@Y0RjEAfPn5go3CvrWMoX "Haskell – Try It Online")
Instead of using modular arithmetic, we generate the list `l` of all strings in the desired order and index into it.
The recursive definition of `l` is similar to [this one](https://codegolf.stackexchange.com/a/74293/20260) for generating all strings, but modified to output strings in the desired order by appending the new character, and with a `tail` to prevent the analogue of leading zeroes.
**From base 94: 31 bytes**
```
foldl(\n->(94*n-33+).fromEnum)0
```
[Try it online!](https://tio.run/##y0gszk7NyfmfbhvzPy0/JyVHIyZP107D0kQrT9fYWFtTL60oP9c1rzRX0@B/bmJmnoKtQkFRZl6JgopCbmKBQrpCtJKSjlIMiKgDMxSBpJk/kDDSzbNQiv3/LzktJzG9@L9uckEBAA "Haskell – Try It Online")
Iterates over the characters `c` of the string, updating the current value `n` to `94*n-33+fromEnum c`.
[Answer]
# [Python 2](https://docs.python.org/2/), 40 + 45 = 85 bytes
**To base 94: 40 bytes**
```
f=lambda n:n*"?"and f(n/94)+chr(n%94+33)
```
[Try it online!](https://tio.run/##DcfNCoQgEADgu08hQTCzHcoZLwaxz2I/olCzEkb09Lbf7ctPiT@hWsO0@2NevZZRPs238bLqANI7i90ST5DW2Y4Z6x3Tvmkz5jNJgQBJ8lUAEeugjHKsnFU00D@WmInMCw "Python 2 – Try It Online")
Python 3 would need 1 extra byte for `//` in place of `/`.
**From base 94: 45 bytes**
```
g=lambda s:s>''and g(s[:-1])*94+ord(s[-1])-33
```
[Try it online!](https://tio.run/##K6gsycjPM/r/P902JzE3KSVRodiq2E5dPTEvRSFdozjaStcwVlPL0kQ7vygFyAXxdI2N/5dnZOakKhhaFRRl5pVopGtk5hWUlmhoamr@V1dU51JXAuI6EA3imPkDCSPdPAt1AA "Python 2 – Try It Online")
**Both to and from base 94: 86 bytes**
```
h=lambda x:x*'?'and h(x/94)+chr(x%94+33)if x<''else x>''and h(x[:-1])*94+ord(x[-1])-33
```
[Try it online!](https://tio.run/##NcpNCsIwFATgfU4RBXlJS7F5L4gp/hzBA4iLaisJ1LTUinHj1WO6cDEzfDDDZ7K9xxjtvqsf16bmoQoZHKH2DbcirI2W@c2OIqyMzomku/OwA2i7Z8vDAf6/c1Woi8zSpx@bxFkFUXxb17VcVcPo/CSscH54TUJKGUummCFmNMMSEzQSISoGC2CwTPnOO2NzSoWF38IP "Python 2 – Try It Online")
A Frankenstein's monster stitched from the two above functions that turns out just barely longer than their byte total. Since this function accepts both numbers and strings, care must be taken not to produce an error caused by an illegal operation by acting on the wrong type.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), (34 + 44) = 78 bytes
The 'Decimal to Base94' function prints the Base94 number to STDOUT, whereas the 'Base94 to Decimal' function actually returns the integer.
---
### Decimal to Base94:
```
f(n){n&&f(n/94)+putchar(n%94+33);}
```
[Try it online!](https://tio.run/##S9ZNT07@/z9NI0@zOk9NDUjrW5poaheUliRnJBZp5KlammgbG2ta1/7PzCtRyE3MzNPQVKjmUkjTMNC0VoApU4/JU9e0BokaYhW1NMYubIJV2MjACIfhJkbGxkZGWOyo/Q8A "C (gcc) – Try It Online")
### Base94 to Decimal:
```
n;f(char*s){for(n=0;*s;n=n*94+*s++-33);n=n;}
```
[Try it online!](https://tio.run/##S9ZNT07@/z/POk0jOSOxSKtYszotv0gjz9bAWqvYOs82T8vSRFurWFtb19hYE8S3rv2fmVeikJuYmaehqVDNpVBQBOSnaSippsTkKekoAFlKmprW2MRjcMrU4daiiEvKzB@XjJFungVYrvY/AA "C (gcc) – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), Score 10 bytes
*-4 bytes overall thanks to @KevinCruijssen*
## [05AB1E](https://github.com/Adriandmen/05AB1E), 5 bytes
```
žQ¦Åв
```
[Try it online!](https://tio.run/##yy9OTMpM/f//6L7AQ8sOt17Y9P@/oYmRsbGRkSEA "05AB1E – Try It Online")
# [05AB1E](https://github.com/Adriandmen/05AB1E), 5 bytes
```
žQ¦Åβ
```
[Try it online!](https://tio.run/##yy9OTMpM/f//6L7AQ8sOt57b9P9/tJKRko6Cki6IyAMRFkqxAA "05AB1E – Try It Online")
[Answer]
# [W](https://github.com/A-ee/w), 4 [bytes](https://github.com/A-ee/w/wiki/Code-Page)
Encoding/Decoding program, it's bidirectional.
```
lpQB
```
# Explanation
```
lp   % All printable characters, including the space.
  Q  % Extract all of the string except for the first item.
   B % Convert the input to/from base 94 using the custom base.
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~44~~ 43 + 32 = 75 bytes
-1 byte thanks to [xnor](https://codegolf.stackexchange.com/users/20260/xnor).
**Base 10 to base 94:**
```
g 0=""
g n=g(div n 94)++[['!'..]!!mod n 94]
```
[Try it online!](https://tio.run/##y0gszk7Nyfn/P13BwFZJiStdIc82XSMls0whT8HSRFNbOzpaXVFdTy9WUTE3PwUsGPs/NzEzT8FWISWfSwEICooy80oUVBTSFQxNjIyNjYwM0YSNDIwM/gMA "Haskell – Try It Online")
**Base 94 to base 10:**
```
foldl(#)0
n#c=n*94+fromEnum c-33
```
[Try it online!](https://tio.run/##y0gszk7NyfmfbhvzPy0/JyVHQ1nTgCtPOdk2T8vSRDutKD/XNa80VyFZ19j4f25iZp6CrUJKPpcCEBQUZeaVKKgopCsoGenmWSihC5r5K/3/l5yWk5he/F83uaAAAA "Haskell – Try It Online")
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 4 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
Base-94 I/O as an array of characters. Output for `0` is an empty array, input for `0` can either be an empty array or `["!"]`.
```
;ìEÅ
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=O%2bxFxQ&input=WwoxNDIzMzIyMQpbIjIiLCItIiwibiIsIjgiXQpdLW1S)
[Answer]
# [Bash](https://www.gnu.org/software/bash/) + GNU utilities, Score 37 + 70 = 107 bytes
---
# Base 10 to Base 94: 37 bytes
```
dc<<<94o$1p|sed 's/\b \|$/ 33+P/g'|dc
```
[Try the test suite online!](https://tio.run/##NYxBCsIwEEX3nuJTAl2IpJnJJhA9gwfoxibRuplI4zJ3H6vg5sN78P5ya6ve6wbBUzDBITCCB020gydmIncAct0HKGmtOAkGIzhfMPxkK28Y0ZxijMFX4169lYyx2XnB3I0F8/FqH2PPSfG/@aa5SlHVDw "Bash – Try It Online")
Input is passed as an argument, and output is on stdout.
This works for inputs from \$0\$ through \$94^{23}-1.\$
This is probably sufficient, since \$94^{23}-1\$ is a huge number (46 decimal digits long — `2409576021839340871044919550282633620681129983` in base 10, or `~~~~~~~~~~~~~~~~~~~~~~~` in base 94), and this is already much larger than most languages can handle.
---
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 34 + 43 = 77 bytes
# Encoder
```
f(n){n&&f(n/94)|putchar(n%94+33);}
```
[Try it online!](https://tio.run/##S9ZNT07@/z9NI0@zOk9NDUjrW5po1hSUliRnJBZp5KlammgbG2ta1/7PzCtRyE3MzNMoy89M0eSq5lIAgjQNIwMjA01rrtr/AA "C (gcc) – Try It Online")
# Decoder
```
r;f(int*s){for(r=0;*s;)r=r*94+*s++-33;s=r;}
```
Takes a wide string as argument.
[Try it online!](https://tio.run/##S9ZNT07@/7/IOk0jM69Eq1izOi2/SKPI1sBaq9has8i2SMvSRFurWFtb19jYuti2yLr2P1CdQm5iZp5GWX5miiZXNZcCEBQUAYXTNJRUU2LylHQU0jR8lMz8lTQ1rblq/wMA "C (gcc) – Try It Online")
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 80 bytes
```
{FromCharacterCode[#~IntegerDigits~94+33]&,FromDigits[ToCharacterCode@#-33,94]&}
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78X52mk15r@7/arSg/1zkjsSgxuSS1yDk/JTVauc4zryQ1PbXIJTM9s6S4ztJE29g4Vk0HpBIiFB2Sj6LFQVnX2FjH0iRWrfZ/QFFmXkl0WrShiZGxsZGRYayOkoKCkk46slBs7P//AA "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 11 or 7 bytes
## Base 10 to base 94: 5 bytes
```
⍘Ｎ✂γ¹
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMMpsTg1uATITNfwzCsoLfErzU1KLdLQ1FEIzslMTtVI11Ew1NTUtP7/39DEyNjYyMjwv25ZDgA "Charcoal – Try It Online") Link is to verbose version of code. Takes input as a string of decimal digits optionally wrapped in `[]`. Explanation:
```
 Ｎ      Cast input to number
⍘       Base conversion from custom base
   γ    Printable ASCII (including space)
  ✂ ¹   Slice off the first character
        Implicitly print
```
## Base 94 to base 10: 6 bytes
```
Ｉ⍘Ｓ✂γ¹
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMM5sbhEwymxODW4BMhP1/DMKygtgbI1dRSCczKTUzXSdRQMNYHA@v9/I908i/@6ZTkA "Charcoal – Try It Online") Link is to verbose version of code. Note: Due to the way Charcoal parses input, if the input looks like JSON then Charcoal will input it as JSON instead of a literal string. To avoid that, quote the input and wrap it in `[]`s, e.g. to input `[0]` use `["[0]"]`. Explanation:
```
  Ｓ     Cast input to string
 ⍘      Base conversion from custom base
    γ   Printable ASCII (including space)
   ✂ ¹  Slice off the first character
Ｉ       Cast from integer
        Implicitly print
```
## Bidirectional: 7 bytes
```
⁺ω⍘Ａ✂γ¹
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRCMgp7RYo1xHwSmxODW4BCiUruGZV1BaoqGpoxCck5mcqpGuo2CoCQTW//9HKxnp5lkoxf7XLcsBAA "Charcoal – Try It Online") Link is to verbose version of code. Takes input as JSON wrapped in `[]`s. Explanation:
```
   Ａ    Input JSON element
  ⍘     Base conversion to or from custom base
     γ  Printable ASCII (including space)
    ✂ ¹ Slice off the first character
⁺ω      Concatenate empty string (casts result to string)
        Implicitly print
```
[Answer]
# [Python 2](https://docs.python.org/2/), 53 + 46 = 99 bytes
**Base 10 to base 94:**
```
n=input();r=''
while n:r=chr(n%94+33)+r;n/=94
print r
```
[Try it online!](https://tio.run/##LY2xDoMwEEP3@4pbqoAYgIQFUEa6dukPtOlJoFaX6BTU8vVponayLT3b4YirZ52cfxBaVEolthuHPVb1LFYpeK/bi5AnsW6Vik/j0BhTNzJza8cBgmwcUVJuwp@9yk4TIEY5iiDShxyWByjeUYi4XM6LiJcfcBe6PVMHPYwG8qjudA6DNkbr/gs "Python 2 – Try It Online")
**Base 94 to base 10:**
```
lambda s:reduce(lambda a,b:a*94+ord(b)-33,s,0)
```
[Try it online!](https://tio.run/##LU09D4IwFNz7K54ubRUSA8YoCSOuLI4uLX0EIrbNo0RZ/OtIo8N9JZc7P4fO2WxpnEEogTjnrC3vy6Ce2igYC0IzNSj@WSW6ULvLce/ICC3TPE/G5CAXT70N0Ire@ikIKVncYa@uHxBuNGHBAALNUQDwjQ3EQxZ9gz5AVV8rIke/giZUj4VvOOPbFZ@oMZzqlbLUnvkX "Python 2 – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), ~~47 + 51 = 98~~ 40 + 42 = 82 bytes
*Saved 12 bytes, inspired by @ovs 's suggestion.*  
*Saved 1 byte by replacing `len(s)` with `s>[]`, stolen from [@xnor's Python answer](https://codegolf.stackexchange.com/a/203050/92237).*
```
f=lambda n:n*`n`and f(n/94)+chr(n%94+33)
g=lambda s:s>[]and ord(s.pop())-33+g(s)*94
```
[Try it online!](https://tio.run/##NY5BboMwEEX3PsUECckOhiY2qgpScoJKPUAUNRRKYgkGy@NNNr069VB1M57//5sv@2d8LGjWdTxN3fw1dIAt7m9463CAUeJLU6uifwSJeVMX1ipx/weppfPlytwSBkmVX7xUqrS2uEtS@6Ze3eyXEIGeJMS4BJgcfoNDNiqKg8NWAKCGTw0EJ5g7LymGFAXn9UZX5CcXUy2DCXEYJbKgd0cxGZceuLnfaq9MmeSmD3C@gazHvyMf0j1k@QA5QVmeYdsyyEGiJo1Gk1HrAUrYiWOamWhsen5EU7PaCXMwnL5@iGNtrDWGKVPi2y8)
`f` takes in an integer, and returns the base 94 string. Returns the empty string for `0`.  
`g` takes in a list of characters, and returns an integer. If input is a empty list (representing an empty string), `False` is returned in stead of `0`, which is functionally equivalent in Python.
### [Python 2](https://docs.python.org/2/), 82 bytes
This is the bidirectional function that combines the previous 2 functions, with the same total byte count. Utilize the fact that in Python 2, `0 < positive int < empty list < non-empty list`.
```
f=lambda n:n>[]and ord(n.pop())-33+f(n)*94or n<[]and n*`n`and f(n/94)+chr(n%94+33)
```
[Try it online!](https://tio.run/##JY5BbsMgEEX3nGJiyRLEOE3AquqoyQkq9QBR1Dh2rSDZY8SwyaZXdweygfn/vz/gn/GxoFnX8TR1833oAI94vlw7HGAJg8SdX7xUqra2GiWqbdssAfDzReD2hrc0cPTWNqrqH0Fi2TaVtWp1s19CBHqSECO3Joe/4DAZO4qDw6MAQA0/GghOMHdeUgwcBed1pnfkJxf5@QQy4jDyH1jQl6PIxqWHtLnPa6@JMuyOMucZfOlc8oH7UJQDlAR1fYY8FVCCRE0ajSaj1j3UsBEHPgvRWr7@RNsktRFmb1L6/i0OjbHWmESZGj/@AQ "Python 2 – Try It Online")
**Input/output**: If `n` is a list of characters, return the converted integer. If `n` is an integer, returns its base 94 string.
[Answer]
# [Ruby](https://www.ruby-lang.org/), 33 + 34 = 67 bytes
## Encode (33):
```
f=->n{n>0?f[n/94]+""<<n%94+33:""}
```
[Try it online!](https://tio.run/##KypNqvz/P81W1y6vOs/OwD4tOk/f0iRWW0nJxiZP1dJE29jYSkmp9n9BaUmxQrSBjqGOpbGOpYmOkYERkGNiZGxsZGQYq5ebWKChlqb5HwA "Ruby – Try It Online")
## Decode (34):
```
->s{i=0;s.bytes{|x|i=i*94+x-33};i}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1664OtPWwLpYL6myJLW4uqaiJtM2U8vSRLtC19i41jqz9n9BaUmxQrS6orqOuhIQ14FoEMfMAEgY6eZZqMfq5SYWaKilaf4HAA "Ruby – Try It Online")
Thanks Value Ink, as usual, for some byte trimming.
[Answer]
## [K (ngn/k)](https://bitbucket.org/ngn/k), 9 + 10 = 19 bytes
## To base 94, 9 bytes
```
`c$33+94\
```
[Try it online!](https://tio.run/##y9bNS8/7/z/NKiFZxdhY29Ik5n@auoKBgqGCpbGCpYmCkYERkGNiZGxsZGT4HwA "K (ngn/k) – Try It Online")
## From base 94, 10 bytes
```
94/-33+`i$
```
[Try it online!](https://tio.run/##y9bNS8/7/z/NytJEX9fYWDshU@V/mrqGkpK1UgyIqAMzFIGkmT@QMNLNs1DS5PoPAA "K (ngn/k) – Try It Online")
## [J](http://jsoftware.com/), 15 + 13 = 28 bytes
## To base 94, 15 bytes
```
[:u:33+94&#.inv
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/o61KrYyNtS1N1JT1MvPK/mtyKXClJmfkK2hYp2kqqNkBlRoqWBorWJooGBkYATkmRsbGRkaGXP8B "J – Try It Online")
## From base 94, 13 bytes
```
94#._33+a.i.]
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/LU2U9eKNjbUT9TL1Yv9rcilwpSZn5CtoWKdpKqjZKagrqlsrqCuBiDowC8w38weRRrp5Fupc/wE "J – Try It Online")
[Answer]
# x86 32-bit machine code, 14 + 17 = 31 bytes
atoi: explicit-length string input, pointer and length. Returns `uint32_t`  
itoa: pointer to the end of a buffer, returns pointer to the first digit. Only works for non-negative `int32_t` - would cost 1 extra byte to `xor edx,edx` before div instead of `cdq` to sign-extend.
objdump -d -Mintel disassembly of both functions with machine code (the actual answer) and the source. Comments added manually.
```
    ;; input: char *RDI, size_t RCX
    ;; returns: unsigned EDX
    ;; clobbers: EAX temporary to load digits
08049000 <atoi_b94>:
 8049000:       31 c0                   xor    eax,eax               ; EAX = 0 so lodsb zero-extends to 32-bit
 8049002:       99                      cdq                          ; EDX = 0 = total
08049003 <atoi_b94.loop>:
 8049003:       ac                      lods   al,BYTE PTR ds:[esi]
 8049004:       6b d2 5e                imul   edx,edx,0x5e          ; total *= base
 8049007:       8d 54 02 df             lea    edx,[edx+eax*1-0x21]  ; total += char_to_int(digit)
 804900b:       e2 f6                   loop   8049003 <atoi_b94.loop>
 804900d:       c3                      ret    
```
You could call atoi from C if you declare the return value as a 128-bit integer, or a struct. itoa uses different calling convention.
```
    ;; input: unsigned EAX, char *RDI=end_ptr
    ;; result: converts into base94 in printing order in the buffer
    ;; returns: RDI=pointer to the first digit.  Caller knows where the end is because it passed that arg
    ;; clobbers: EDX
0804900e <itoa_end_base94>:
 804900e:       6a 5e                   push   0x5e
 8049010:       59                      pop    ecx      ; ECX = base
08049011 <itoa_end_base94.toascii_digit>:                         ; do{
 8049011:       99                      cdq    
 8049012:       f7 f1                   div    ecx                  ; EAX = quotient, EDX = remainder
 8049014:       83 c2 21                add    edx,0x21
 8049017:       4f                      dec    edi
 8049018:       88 17                   mov    BYTE PTR [edi],dl    ; *(--p) = digit
 804901a:       85 c0                   test   eax,eax            ; }while(x)
 804901c:       75 f3                   jne    8049011 <itoa_end_base94.toascii_digit>
 804901e:       c3                      ret    
```
next address is 0x1f, total size = 0x1f - 0 = 31 bytes.
Some of the comments use 64-bit registers; I switched to 32-bit to save 2 bytes in single-byte `dec edi` vs. `dec rdi` REX opcode modrm.
[**Try it online!**](https://tio.run/##hVVNb@M2EL3rV0wPBezEcuKPtpsYOrgb7yJANgGStAjaDQRKGtlsZFJLUrGTon@96ZCUbDn2ojoIIjmceTPvzYhpjcukeAlzppdvb7lUS2ZgdvUJcI1pZVhSIIwAYOI2R8Mw4aZ1FmicL1EYUMgyZ9w6o331ArE2TJlgMi9kwop6aR1eT@@@BAH5hl@ndzPAbxWcjYM/Zrc3F5efL@/dxmjkLSYT4KKszDmkC6bg6Pbisgeav2Js4PbjQ2Oj0FRK6HOohOZzgRnMLjaHKQFIUNHpbPoABpelVIwAGgmFZBlkfM6N3gBlRvI4IUTNx7lztJYKANm6Z1@w@0yc5whOQVufmU7gFZUMcW1QZNpG8hV0ntLsG3zvmVjgzlNEtwwrgn4hZekheM/fu9iKSPlzQUFvp74IfFkVBD6z4O3L1X3fgwsIRxEkTKOPiAzqi3/SG45d8iFsyHpsXTyOHEmxkTFF77iydmvgsgRwmbg10fWe3i1x04feluyIsolLo7ZE66qwapDiGZXRPk@L92xM31Aq2uBiDlJlqOyOWSAkVZ6j2hOL9V9KukCW5MVa5lxp4xXRB/jIioLOnoRcaVgtUKEzIkzANSSYskojUGOUjPopo0NqIqbmB5RHcmwExo1ksc3Lww7erT3XZaUXdYf4ta0gUZGug6BPF3TKeexwnu8TmUn4@3@lRnZSFC@wkupJA00AEFKEAufM8Ge0hcU5YacyYEFZ2kxdEzQycgEy/lzDOhiAzCKFS8aFZSMiIax8ca3E@/2zvmupk2hw6vXAsgwawW005gNh6k/4gTDaSKLG97Hl/MvdReiZ3NVDzyVrlwlLn1ZMUW/mSi43rMrcfWpD1zyLS@kSJPXzxx5kxU7co04Yll3KxYX2KRiksH5SvB8UE/iHVMQL7Ky7E2f8l3ilvtihM5hYiVKaTpn6gDC3LTT5McOcC4T72d3979MrGAxH459@/uVDML26/HwN48BP3ZakBqceyVcBLLfCr9P2LbIRstyodFsFKgERr30L64omES16NNlaJnY@1mC8AKmD9gS/NU@dlHjQLrXzMd7jOI6vb@OV4gY9ZSeVVidcpEWV4Qn9xE4qwbXJ4tGwv9hxl5C7wZ67PCPa7u4vbn67jz9dXs2ub1oDr5l4ujweDWnoDR5rOdflcMk3AzV9T3KBYm4WdnKFrvo98DCt7iyVX4UfysLqBE7XH04PSNpl2hn0ai32oJE3oem264Wa74MgB/Vga4/xtB7joc9nFy@suFnIyjiIAleF1VXUHJJCfN@2WsNxu/1duq1l2dSlrQKNhpwlRRu2ZXnQKsSBOlDB19zEcyWrstNI/IfIhexYUTWb3W43eHv7N80LNtdvYVZvR4PxcDQaDgf/AQ "Assembly (fasm, x64, Linux) – Try It Online") with a test harness that converts an assemble-time-constant value to a string and back, prints the result, and checks for integer equality. Change the assembler command line option to `-dTESTVAL=94` or whatever to test other values. If it prints the right string and exit status is `0`, it worked.
I used FASM on TIO so I could make 32-bit code; TIO's will only assemble 64-bit object files with NASM/YASM, but FASM can output an executable directly, no linker involved.
---
For "normal" asm [atoi](https://stackoverflow.com/questions/19309749/nasm-assembly-convert-input-to-integer/49548057#49548057) and [itoa](https://stackoverflow.com/questions/13166064/how-do-i-print-an-integer-in-assembly-level-programming-without-printf-from-the/46301894#46301894), see my answers on those linked SO questions. Golfing them was straightforward, with only one significant change: use explicit-length strings for itoa so we can use `loop` instead of having to check for a terminator before `tot = tot*base + digit`. And turning `itoa` into a function that just does the conversion into the caller's buffer.
I also made the `94` and `33` assemble-time symbolic constants (in the TIO link)
I had hoped we might get some use out of `stosb`, but we need to go backwards, and I couldn't justify having `atoi` depend on DF=0 while having `itoa` use `std` without `cld`. Also, getting the remainder into AL means swapping with EDX, but then we need to swap back for the next `div`.
```
;; alternate worse version for after DIV
     std
     xchg   eax, edx
     add    al, ZERODIGIT        ; 2 bytes
     stosb                       ; *p-- = digit.  would also need a scasb or inc edi at the end to fix
     xchg   eax, edx
     cld
```
That's *nearly* break-even, IIRC one byte longer, but does `*p-- = digit` instead of the `*--p = digit` that we actually want. (Caller could change to pass a pointer to the last element of the buffer, instead of past the end, but I don't think we can justify returning a pointer to the uninitialized space below the first digit. So that would cost an extra `inc edi` after the loop.
[Answer]
# [Raku](https://raku.org) (raku -p) 60+42 Bytes = 102 Bytes
```
# convert base-10 to base-94
$!='';while $_ {$!=(chr $_%94+33)~$!;$_=$_.Int div 94};$_=$!
# convert base-94 to base-10
$!=0;$!=94*$!+$_-33 for $_.comb».ord;$_=$!
```
[Answer]
# [Red](http://www.red-lang.org), 68 + 58 = 126 bytes
## To base 94, 68 bytes
```
f: func[n][head either n > 0[append f n / 94 #"!"+(n % 94)][copy""]]
```
[Try it online!](https://tio.run/##FcyxCsMgFIXhPU9xaim0lFKjWdIhD9H1cgfRK2YxIsnQp7fmbB/8nCqhfSUQDy1@EI/sKTMlcQGy7kkqMhZocqVIDoidb8wTruqinveMW8eDyW/lpxRzi1sV51PPSGPEbM/YaNMxGWuNGZkG9JW65h3UQ/Va1HnMA7c/ "Red – Try It Online")
## From base 94, 58 bytes
```
g: func[s][either""= s[0][(-33 + take/last s)+(94 * g s)]]
```
[Try it online!](https://tio.run/##PY3NCsIwEITveYp1T9USFCvSCvoKgtdlhdBuf9BGSeLVV4@RVucyHwMz46SJF2mIY3eA9mVr8kwyhF4c4hE8bZgyXRSQQzA3Wd@ND@CXeVbtYAVdQubYPpyYugcPpCAJcbLrD97/YDHT/jzDVtsSFU/FpxtsAEp7YxpDfcLvBSuOHw "Red – Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/), ~~36~~ 32 + ~~26~~ 23 = 55 bytes
**To base 94:** (Commandline options: `-Minteger -n`)
```
do{print chr$_%94+33}while$_/=94
```
[Try it online!](https://tio.run/##K0gtyjH9/z8lv7qgKDOvRCE5o0glXtXSRNvYuLY8IzMnVSVe39bS5P9/QxMjY2MjI8N/@QUlmfl5xf91fYHqU9NTi/7r5gEA "Perl 5 – Try It Online")
**From base 94:** (Commandline Options: `-pF`)
```
map$\=$\*94-33+ord,@F}{
```
[Try it online!](https://tio.run/##K0gtyjH9/z83sUAlxlYlRsvSRNfYWDu/KEXHwa22@v9/I908i3/5BSWZ@XnF/3V9TfUMDA3@6xa4AQA "Perl 5 – Try It Online")
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 62 + 27 = 89 bytes
**To Base 94:**
```
param($a)for(;$a){$a-=$r=$a%94
$a/=94
$n=[char]($r+33)+$n}"$n"
```
[Try it online!](https://tio.run/##RY9dCsIwEITfc4o1rDalLdYkqEXiFTyAiASJP1DTGgWFWq9ek1bwab6dnYWdunoadz@bsuzwURUSFDRdrZ2@MtTxsXJs5bVBnSl0CvW4kAT1VAWxans4a7dj6BIh4gRtS9HSriV4LE@/Zf7iC3lI4T/NBGF5ClEUp4TNPNCeCuHxM6AM7qhnnvMQnm@GuORCcB6ueGaXUQxvGDcEAC@2TgHNq/YNcB8cZ@6eJzD0CgHv0qCQrYcoTcKn254zc@tvdqTtvg)
**From Base 94:**
```
$args|%{$n=$n*94+$_-33}
+$n
```
Expects input via [splatting](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting).
[Try it online!](https://tio.run/##Rc7RCoIwFAbg@z3FSY6ZqaDbqLwweoMeIEIklgY2bV4kqL362pTo7js//4G/bd5CdZWoa4131TxTDhkMGgtVdqM7oMxQblMeYB4xNpEApZ4I3usyu9yqQl3jnu75LYT/lTCy8bwQYj80cIySWR@jlC3hyprP3p2NaUyXOo3kwX5wyhiliQ8juAMBwIdsQ0DRt2Ye5jZRojNew2/2yVRM7tgqRMel7AR262V2JF7z15VM@gs)
[Answer]
# [Julia 1.0](http://julialang.org/), 40+46=86 bytes
### To Base 64, 40 bytes
```
!x=reverse(join('!'.+digits(x,base=94)))
```
### From Base 64, 46 bytes
```
~x=sum(@. 94^(length(x)-1:-1:0)*((x...,)-'!'))
```
[Try it online!](https://tio.run/##VY1BCoMwFET3nsJk4/9Wg8ZQaovgDXqBUrA0aMQqGG2z8uqpUAoJzGLgMfP6dVBNbqwlpprlW85aQj@pESISscNTtWrRYJJHo2VVCkS8bKbS6wtqFpbiDoMc26UDg2l@3pNhDGAYYwmm@wOirXU3fUICGQa/ugElFIPgD3IH3KhLysJBm0eEN/L@eMZd1/HqyQQvCs5dJ0/HE0X7BQ "Julia 1.0 – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 172 bytes
```
def t(n):return"0"if n<1 else t(n//94).lstrip("0")+''.join(map(chr,range(33,127)))[n%94]
def f(n):return ord(n)-33 if len(n)<2 else f(n[1:])+(ord(n[0])-33)*(94**(len(n)-1))
```
[Try it online!](https://tio.run/##TY3LCoMwFET3fkUQivf6zgOK4p@IC6mxWuxVYrro16exLtrlYc7MbG87rSSdG/TILBDWRtuXobAM55FRw5ledn0kRVEpzJfdmnkDH2MSRfljnQme/Qa3yaSmp7sGKVMurojY0qVSXXAMj79htprBUyYl8weLJg@NOF@81vK6wwS@Ult2h4cxVCqO4XQzjug2M5MFC1wJKYXgmPruHyIG7gM "Python 3 – Try It Online")
Based off [this](https://stackoverflow.com/questions/2267362/how-to-convert-an-integer-in-any-base-to-a-string) answer on StackOverflow
]