[Question]
  [
In [Salesforce CRM](http://salesforce.com), every object has 15-character alphanumeric ID, which is case-sensitive. If anyone's curious, actually it's [base-62 number](https://help.salesforce.com/apex/HTViewSolution?id=000004383).
However, tools used for data migration and integration may or may not support case sensitivity. To overcome that, IDs can be safely converted to 18-character case-insensitive alphanumeric IDs. In that process 3-character alphanumeric checksum is appended to the ID. The conversion algorithm is:
**Example**:
```
a0RE000000IJmcN
```
1. Split ID into three 5-character chunks.
```
a0RE0  00000  IJmcN
```
2. Reverse each chunk.
```
0ER0a  00000  NcmJI
```
3. Replace each character in every chunk by `1` if it's uppercase or by `0` if otherwise.
```
01100  00000  10011
```
4. For each 5-digit binary number `i`, get character at position `i` in concatenation of uppercase alphabet and digits 0-5 (`ABCDEFGHIJKLMNOPQRSTUVWXYZ012345`).
```
00000 -> A,
00001 -> B,
00010 -> C, ..., 
11010 -> Z, 
11011 -> 0, ...,
11111 -> 5`
```
Yielding:
```
M  A  T
```
5. Append these characters, the checksum, to the original ID.
**Output**:
```
a0RE000000IJmcNMAT
```
Write program or function which takes 15-character alphanumeric (ASCII) string as input and returns 18-character ID.
Input validation is out of scope of this question. Programs may return any value or crash on invalid input.
Please, don't use Salesforce propretiary languages' features that make this challenge trivial (such as formula `CASESAFEID()`, converting `Id` to `String` in APEX &c).
### Test Cases
```
a01M00000062mPg    -> a01M00000062mPgIAI
001M000000qfPyS    -> 001M000000qfPySIAU
a0FE000000D6r3F    -> a0FE000000D6r3FMAR
0F9E000000092w2    -> 0F9E000000092w2KAA
aaaaaaaaaaaaaaa    -> aaaaaaaaaaaaaaaAAA
AbCdEfGhIjKlMnO    -> AbCdEfGhIjKlMnOVKV
aBcDEfgHIJKLMNO    -> aBcDEfgHIJKLMNO025
```
  
[Answer]
# Pyth, ~~23~~ 22 bytes
*1 byte saved by [FryAmTheEggman](https://codegolf.stackexchange.com/questions/69127/convert-salesforce-15-character-id-to-18-character#comment168306_69131).*
```
sm@s+JrG1U6i}RJ_d2c3pz
```
[Try it online.](http://pyth.herokuapp.com/?code=sm%40s%2BJrG1U6i%7DRJ_d2c3pz&input=a0RE000000IJmcN&debug=0) [Test suite.](http://pyth.herokuapp.com/?code=sm%40s%2BJrG1U6i%7DRJ_d2c3pz&test_suite=1&test_suite_input=a01M00000062mPg%0A001M000000qfPyS%0Aa0FE000000D6r3F%0A0F9E000000092w2%0Aaaaaaaaaaaaaaaa%0AAbCdEfGhIjKlMnO&debug=0)
This might be the first time I've used the `p`rint instruction in golfing.
### Explanation
```
     JrG1                   save uppercase alphabet in J
                     z      input string
                    p       print it without newline
                  c3        split into 3 parts
 m              d           for each part:
               _              reverse
            }R                map characters to being in
              J                 uppercase alphabet (saved in J)
           i     2            parse list of bools as binary
  @                           get correct item of
     J                          uppercase alphabet (saved in J)
   s+    U6                     add nums 0-5 to it
s                           concatenate and print
```
[Answer]
## Ruby, 97 bytes
```
->s{s+s.scan(/.{5}/).map{|x|[*?A..?Z,*?0..?5][x.reverse.gsub(/./){|y|y=~/[^A-Z]/||1}.to_i 2]}*''}
```
```
->s{               # define an anonymous lambda
s+                 # the original string plus...
s.scan(/.{5}/)     # get every group of 5 chars
.map{|x|           # map over each group of 5 chars...
[*?A..?Z,*?0..?5]  # build the array of A-Z0-5
[                  # index over it with...
x.reverse          # the 5-char group, reversed...
.gsub(/./){|y|     # ... with each character replaced with...
y=~/[^A-Z]/||1     # ... whether it's uppercase (0/1)...
}.to_i 2           # ... converted to binary
]                  # (end index)
}*''               # end map, join into a string
}                  # end lambda
```
This one's got some really neat tricks.
My original instinct for splitting the string into groups of 5 chars was `each_slice`:
```
irb(main):001:0> [*1..20].each_slice(5).to_a
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
```
Turns out that's waaay too long compared to a simple regex (`x.chars.each_slice(5)` vs. `x.scan(/.{5}/)`). This seems obvious in hindsight, but I never really thought about it... perhaps I can optimize some of my old Ruby answers here.
The thing I'm most proud of in this answer, though, is this piece of code:
```
y=~/[^A-Z]/||1
```
Alright, so here's some background for the non-Rubyists. Ruby completely separates booleans (`TrueClass`, `FalseClass`) from integers/numbers (`Numeric`)‚Äîthat means there's no automatic conversion from true to 1 and false to 0 either. This is annoying while golfing (but a good thing... for all other purposes).
The na√Øve approach to checking whether a single character is uppercase (and returning 1 or 0) is
```
y.upcase==y?1:0
```
We can get this down a little further (again, with a regex):
```
y=~/[A-Z]/?1:0
```
But then I really started thinking. Hmm... `=~` returns the index of a match (so, for our single character, always `0` if there's a match) or `nil` on failure to match, a falsy value (everything else except `FalseClass` is truthy in Ruby). The `||` operator takes its first operand if it's truthy, and its second operand otherwise. Therefore, we can golf this down to
```
y=~/[^A-Z]/||1
```
Alright, let's look at what's happening here. If `y` is an uppercase letter, it will fail to match `[^A-Z]`, so the regex part will return `nil`. `nil || 1` is `1`, so uppercase letters become `1`. If `y` is anything but an uppercase letter, the regex part will return `0` (because there's a match at index `0`), and since `0` is truthy, `0 || 1` is `0`.
... and only after writing all of this out do I realize that this is actually the same length as `y=~/[A-Z]/?1:0`. Haha, oh well.
[Answer]
# [MATL](https://esolangs.org/wiki/MATL), 24 bytes
```
j1Y24Y2hG5IePtk=~!XB1+)h
```
Uses [current version (9.1.0)](https://github.com/lmendo/MATL/releases/tag/9.1.0) of the language/compiler.
### Examples
```
>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a0RE000000IJmcN
a0RE000000IJmcNMAT
>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a01M00000062mPg
a01M00000062mPgIAI
```
### Explanation
```
j            % input string
1Y2          % predefined literal: 'ABC...Z'
4Y2          % predefined literal; '012...9'
h            % concatenate into string 'ABC...Z012...9'
G            % push input string
5Ie          % reshape into 5x3 matrix, column-major order
P            % flip vertically
tk=~         % 1 if uppercase, 0 if lowercase
!XB1+        % convert each column to binary number and add 1
)            % index 'ABC...Z012...9' with resulting numbers
h            % concatenate result with original string
```
[Answer]
# JavaScript (ES6), 108
```
x=>x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0)+[0,5,10].map(n=>x+='ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'[t>>n&31])&&x
```
**Test**
```
f=x=>x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0)+[0,5,10].map(n=>x+='ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'[t>>n&31])&&x
// Less golfed
U=x=>{
  x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0); // build a 15 bit number (no need to explicit reverse)
  // convert 't' to 3 number of 5 bits each, then to the right char A..Z 0..5
  [0,5,10].forEach(n=> // 3 value for shifting
    x += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345' // to convert value to char
     [ t>>n&31 ] // shift and mask
  );
  return x
}
console.log=x=>O.innerHTML+=x+'\n';
;[
  ['a01M00000062mPg','a01M00000062mPgIAI']
, ['001M000000qfPyS','001M000000qfPySIAU']
, ['a0FE000000D6r3F','a0FE000000D6r3FMAR']
, ['0F9E000000092w2','0F9E000000092w2KAA']
, ['aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaaAAA']
, ['AbCdEfGhIjKlMnO','AbCdEfGhIjKlMnOVKV']
, ['aBcDEfgHIJKLMNO','aBcDEfgHIJKLMNO025']
].forEach(t=>{
  var i=t[0],x=t[1],r=f(i);
  console.log(i+'->'+r+(r==x?' OK':' Fail (expected '+x+')'));
})
```
```
<pre id=O></pre>
```
[Answer]
## CJam, 27 bytes
```
l_5/{W%{_el=!}%2bH+43%'0+}%
```
[Run all test cases.](http://cjam.aditsu.net/#code=qN%2F%7BS%2F0%3D%3AL%3B%0A%0AL_5%2F%7BW%25%7B_el%3D!%7D%252bH%2B43%25'0%2B%7D%25%0A%0A%5DoNo%7D%2F&input=a01M00000062mPg%20%20%20%20-%3E%20a01M00000062mPgIAI%0A001M000000qfPyS%20%20%20%20-%3E%20001M000000qfPySIAU%0Aa0FE000000D6r3F%20%20%20%20-%3E%20a0FE000000D6r3FMAR%0A0F9E000000092w2%20%20%20%20-%3E%200F9E000000092w2KAA%0Aaaaaaaaaaaaaaaa%20%20%20%20-%3E%20aaaaaaaaaaaaaaaAAA%0AAbCdEfGhIjKlMnO%20%20%20%20-%3E%20AbCdEfGhIjKlMnOVKV%0AaBcDEfgHIJKLMNO%20%20%20%20-%3E%20aBcDEfgHIJKLMNO025)
A fairly straightforward implementation of the spec. The most interesting part is the conversion to characters in the checksum. We add 17 to the result of each chunk. Take that modulo 43 and add the result of that to the character `'0`.
[Answer]
# Japt, 46 bytes
```
U+U¬Æf"[A-Z]" ?1:0} f'.p5)¬Æw n2 +A %36 s36 u} q
```
Not too happy with the length, but I can't find a way to golf it down.
[Try it online!](http://ethproductions.github.io/japt?v=master&code=VSuhWGYiW0EtWl0iID8xOjB9IGYnLnA1Ka53IG4yICtBICUzNiBzMzYgdX0gcQ==&input=ImEwUkUwMDAwMDBJSm1jTiI=)
[Answer]
# JavaScript (ES6), ~~137~~ 132 bytes
```
s=>s+s.replace(/./g,c=>c>"9"&c<"a").match(/.{5}/g).map(n=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"[0|"0b"+[...n].reverse().join``]).join``
```
*4 bytes saved thanks to [@’ä’ì‘º’É’ê’ä’É’à‘≤’ç‘º](https://codegolf.stackexchange.com/users/41247/%d5%8a%d5%93%d4%bc%d5%83%d5%90%d5%8a%d5%83%d5%88%d4%b2%d5%8d%d4%bc)!*
## Explanation
This challenge is not suited for JavaScript at all. There's no short way to reverse a string and it looks like the shortest way to convert the number to a character is to hard-code each possible character.
```
s=>
  s+                                   // prepend the original ID
  s.replace(/./g,c=>c>"9"&c<"a")       // convert each upper-case character to 1
  .match(/.{5}/g).map(n=>              // for each group of 5 digits
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
    [0|"0b"+                            // convert from binary
      [...n].reverse().join``]          // reverse the string
  ).join``
```
If the digits in the checksum were allowed to be lower-case it could be done in 124 bytes like this:
```
s=>s+s.replace(/./g,c=>c>"9"&c<"a").match(/.{5}/g).map(n=>((parseInt([...n].reverse().join``,2)+10)%36).toString(36)).join``
```
## Test
```
var solution = s=>s+s.replace(/./g,c=>c>"9"&c<"a").match(/.{5}/g).map(n=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"[0|"0b"+[...n].reverse().join``]).join``
```
```
<input type="text" id="input" value="AbCdEfGhIjKlMnO" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>
```
[Answer]
## MATLAB, 100 98 bytes
```
s=input('');a=flip(reshape(s,5,3))';e=['A':'Z',48:53];disp([s,e(bin2dec(num2str(a~=lower(a)))+1)])
```
A string will be requested as input and the output will be displayed on the screen.
## Explanation
I'm probably using the most straight-forward approach here:
* Request input
* Reshape to 5 (rows) x 3 (columns)
* Flip the row order
* Transpose the matrix to prepare it for being read as binary
* Allocate the ABC...XYZ012345 array
* Compare the character indices of the transposed matrix to its lower-case equivalent and convert the booleans to strings, which are then read as binary and converted to decimal.
* Interpret these decimals (incremented by 1) as indices of the allocated array.
* Display the input with the additional 3 characters
Now below 100 bytes thanks to Luis Mendo!
[Answer]
# C, ~~120~~ 118 bytes
```
n,j;main(c,v,s)char**v,*s;{for(printf(s=v[1]);*s;s+=5){for(n=0,j=5;j--;)n=n*2+!!isupper(s[j]);putchar(n+65-n/26*17);}}
```
Works for any input whose length is a multiple of 5 :)
## Ungolfed
```
n,j;
main(c,v,s) char **v, *s;
{
    for(printf(s = v[1]); *s; s+=5)
    {
        for(n=0, j=5; j--;)
            n=n*2+!!isupper(s[j]);
        putchar(n+65-n/26*17);
    }
}
```
[Answer]
## PHP, ~~186~~ 181 bytes
```
<?$z=$argv[1];$x=str_split($z,5);$l="ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";foreach($x as$y){foreach(str_split(strrev($y))as$a=>$w)$y[$a]=ctype_upper($w)?1:0;$z.=$l[bindec($y)];}echo $z;
```
## Unglofed
```
<?php
$z = $argv[1];
$x = str_split($z,5);
$l = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
foreach($x as $y) {
    foreach( str_split( strrev($y) ) as $a => $w) {
        $y[$a] = ctype_upper($w) ? 1 : 0;
    }
    $z .= $l[bindec($y)];
}
echo $z;
```
I started out thinking I could make it much shorter than this, but I ran out of ideas to make it shorter.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 21 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
;+√≤5 ¬Æ√î¬£B√®X√É√çgB¬¨c6o√É¬¨
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=OyvyNSCu1KNC6FjDzWdCrGM2b8Os&input=WwoiYTAxTTAwMDAwMDYybVBnIgoiMDAxTTAwMDAwMHFmUHlTIgoiYTBGRTAwMDAwMEQ2cjNGIgoiMEY5RTAwMDAwMDA5MncyIgoiYWFhYWFhYWFhYWFhYWFhIgoiQWJDZEVmR2hJaktsTW5PIgoiYUJjREVmZ0hJSktMTU5PIgpdLW1S) (includes all test cases)
```
;+√≤5 ¬Æ√î¬£B√®X√É√çgB¬¨c6o√É¬¨     :Implicit input of string
 +                        :Append
  √≤5                      :Partitions of length 5
     ¬Æ                    :Map
      √î                   :   Reverse
       ¬£                  :   Map each X
;       B                 :     Uppercase alphabet
         √®X               :     Count occurrences of X
           √É              :  End map
            √ç             :  Convert from binary string to integer
             g            :  Index into
;             B           :    Uppercase alphabet
               ¬¨          :    Split
                c         :    Concatenate
                 6o       :    Range [0,6)
                   √É      :End map
                    ¬¨     :Join
```
[Answer]
## Perl, 80 bytes
```
$_.=join"",map{(A..Z,0..5)[oct"0b".join"",map{lc cmp$_}split//,reverse]}/.{5}/g
```
To be run as:
```
perl -ple '$_.=join"",map{(A..Z,0..5)[oct"0b".join"",map{lc cmp$_}split//,reverse]}/.{5}/g'
```
Pretty straightforward except `lc cmp $_` and `oct "0b" . $str` for binary conversion.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 19 18 17 bytes
```
»Æe‚Ç¨√òAs5U·∏Ñ‚Äò·ªã√òA;√òD¬§
```
[Try it online!](https://tio.run/##y0rNyan8///EutRHTWsOz3AsNg19uKPlUcOMh7u7gVzrwzNcDi35//9/okGQqwEYeHrlJvsBAA "Jelly ‚Äì Try It Online")
## Explanation
```
»Æe‚Ç¨√òAs5U·∏Ñ‚Äò·ªã√òA;√òD¬§   Main monadic link
»Æ                   Print (without newline)
  ‚Ç¨                 Map:
 e                   is element of
   √òA                 the uppercase alphabet
     s              Split into chunks of
      5              five
       U            Reverse [each]
        ·∏Ñ           Convert [each] from binary
         ‚Äò          Add 1 [to each]
          ·ªã         Lookup [each] by 1-based index in
                ¬§   (
           √òA        the uppercase alphabet
             ;       join with
              √òD     digits 0-9
                ¬§   )
```
*-1 byte by inspiration from ovs' O5AB1E answer, printing the initial string directly instead of joining it at the end*
*-1 byts because I'm a dumb and didn't realize that `U` vectorizes*
[Answer]
# [Vyxal](https://github.com/Lyxal/Vyxal), ~~18~~ 17 bytes
```
∆õÍúù;5·∫áRvBkAkd+$ƒ∞·πÖ+
```
[Try it Online!](http://lyxal.pythonanywhere.com?flags=&code=%C6%9B%EA%9C%9D%3B5%E1%BA%87RvBkAkd%2B%24%C4%B0%E1%B9%85%2B&inputs=a0RE000000IJmcN&header=&footer=)
My first attempt at golfing in Vyxal.
## Explanation
```
∆õÍúù;5·∫áRvBkAkd+$ƒ∞·πÖ+
∆õ ;                 Map
 Íúù                    Is uppercase?
   5·∫á               Split into chunks of 5
     R              Reverse each
      v             Vectorize
       B              Convert from binary
        kAkd+       Push uppercase letters joined with digits
             $      Swap
              ƒ∞     Index
               ·πÖ    Join into a string
                +   Append to the original string
```
[Answer]
## Python 2, 97 bytes
```
lambda i:i+''.join(chr(48+(17+sum((2**j)*i[x+j].isupper()for j in range(5)))%43)for x in[0,5,10])
```
[Answer]
## PowerShell, 162 bytes
```
function f{param($f)-join([char[]](65..90)+(0..5))[[convert]::ToInt32(-join($f|%{+($_-cmatch'[A-Z]')}),2)]}
($a=$args[0])+(f $a[4..0])+(f $a[9..5])+(f $a[14..10])
```
OK, a lot of neat stuff happening in this one. I'll start with the second line.
We take input as a string via `$args[0]` and set it to `$a` for use later. This is encapsulated in `()` so it's executed and the result returned (i.e., `$a`) so we can immediately string-concatenate it with the results of three function calls `(f ...)`. Each function call passes as an argument the input string indexed in reverse order chunks as a char-array -- meaning, for the example input, `$a[4..0]` will equal `@('0','E','R','0','a')` with each entry as a char, not a string.
Now to the function, where the real meat of the program is. We take input as `$f`, but it's only used way toward the end, so let's focus there, first. Since it's passed as a char-array (thanks to our previous indexing), we can immediately pipe it into a loop with `$f|%{...}`. Inside the loop, we take each character and perform a case-sensitive regex match with `-cmatch` which will result in true/false if it's uppercase/otherwise. We cast that as an integer with the encapsulating `+()`, then that array of 1's and 0's is `-join`ed to form a string. *That* is then passed as the first parameter in the .NET `[convert]::ToInt32()` call to change the binary (base `2`) into decimal. We use that resultant decimal number to index into a string (`-join(...)[...]`). The string is first formulated as a range `(65..90)` that's cast as a char-array, then concatenated with the range `(0..5)` (i.e., the string is `"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"`). All of that is to return the appropriate character from the string.
[Answer]
# Jolf, 30 bytes
Finally, a probably still-jolfable! [Try it here!](http://conorobrien-foxx.github.io/Jolf/#code=K2kgbVpjaTVkLnAxQ8-BQV9IcHUxIlteMV0nMCIy)
```
+i mZci5d.p1CœÅA_Hpu1"[^1]'0"2
    Zci5                      split input into groups of 5
  _m                          map it
        d                      with this function
               _H              reverse H
              A  pu1            and replace in it all uppercase letters with 1
             œÅ      "[^1]'0"    replace all non-ones with zeroes
            C               2   parse as binary integer
         .p1                    get the (^)th member of "A...Z0...9"
```
[Answer]
# Python 3, ~~201 174~~ 138 bytes
Big thanks to Trang Oul for pointing out a function declaration that no longer needed to exist. And Python ternary operators. And some incorrect output. Just...just give him the upvotes.
```
i=input();n='';c=l=15;
while c:c-=1;n+=('0','1')[i[c].isupper()]
while l:v=int(n[l-5:l],2);l-=5;i+=(chr(v+65),str(v-26))[v>25]
print(i)
```
[Answer]
# J, 36 bytes
```
,_5(u:@+22+43*<&26)@#.@|.\]~:tolower
```
Usage: 
```
   (,_5(u:@+22+43*<&26)@#.@|.\]~:tolower) 'a0RE000000IJmcN'
a0RE000000IJmcNMAT
```
[Try it online here.](http://tryj.tk/)
[Answer]
# C#, 171 bytes
I'm not really well-practiced in golfing C#, but here's a shot.
```
s=>{for(var u=s;u.Length>0;u=u.Substring(5)){int p=0,n=u.Substring(0,5).Select(t=>char.IsUpper(t)?1:0).Sum(i=>(int)(i*Math.Pow(2,p++)));s+=(char)(n+65-n/26*17);}return s;}
```
[Answer]
## C# 334
```
string g(string c){string[]b=new string[]{c.Substring(0,5),c.Substring(5, 5),c.Substring(10)};string o="",w="";for(int i=0,j=0;i<3;i++){char[]t=b[i].ToCharArray();Array.Reverse(t);b[i]=new string(t);o="";for(j=0;j<5;j++){o+=Char.IsUpper(b[i][j])?1:0;}int R=Convert.ToInt32(o,2);char U=R>26?(char)(R+22):(char)(R+65);w+=U;}return c+w;}
```
If requested, I'll reverse my code back to readable and post it.
[Answer]
# Python 3, 87 bytes
```
lambda s:s+bytes(48+(17+sum((~s[i+j]&32)>>(5-i)for i in range(5)))%43 for j in(0,5,10))
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 26 bytes
```
S+√∂m!+‚Ä¶'A'Z·πÅs≈Ä6m»Ø‚Üí·∏ã‚Üî‚Ä†o¬±DC5
```
[Try it online!](https://tio.run/##yygtzv7/P1j78LZcRe1HDcvUHdWjHu5sLD7aYJZ7Yv2jtkkPd3Q/apvyqGFB/qGNLs6m////TzQIcjUAA0@v3GQ/AA "Husk ‚Äì Try It Online")
Getting the alphabets takes a lot of bytes. Otherwise, I think this qould be at par with the other languages.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 17 bytes
```
?5√¥v≈æKu√ôyR‚Ç¨.uJC√®?
```
[Try it online!](https://tio.run/##yy9OTMpM/f/f3vTwlrKj@7xLD8@sDHrUtEav1Mv58Ar7//8TDQx9DcDAzCg3IB0A "05AB1E ‚Äì Try It Online")
**Commented**:
```
?                 # print the input
 5√¥               # split into groups of 5
   Œµ              # iterate over the groups:
    ≈æK            #   push [a-zA-Z0-9]
      u           #   convert to uppercase
       √ô          #   deduplicate: [A-Z0-9]
        y         #   push the group
         R        #   reverse it
          ‚Ç¨       #   for each char:
           .u     #     is it uppercase?
             J    #   join into a binary string
              C   #   convert from binary
               √®  #   index into the string
                ? #   print the char at index
```
[Answer]
# [Raku](http://raku.org/), 63 bytes
```
{$_~S:g[((<:Lu>)||.)**5]=flat('A'..'Z',^6)[:2[?¬´$0[4‚Ä¶0;0]]]}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/WiW@LtgqPVpDw8bKp9ROs6ZGT1NLyzTWNi0nsURD3VFdT089Sl0nzkwz2soo2v7QahWDaJNHDcsMrA1iY2Nr/xcnViooqcQr2NopVKcpqMTXKimk5Rcp2CQaGPoagIGZUW5AuoIBnF@YFlAZrJBo4OYK4buYFRm72f0HAA "Perl 6 ‚Äì Try It Online")
* `$_` is the single argument to this function, the Salesforce ID.
* `$_ ~ S:g[regex] = expr` concatenates `$_` with the result of globally replacing the regular expression `regex` with `expr`.
* `<:Lu>` matches any uppercase letter. `(<:Lu>) || .` matches an uppercase letter or any other character. An uppercase letter will be stored in a capture group; other characters won't.
* `((<:Lu>) || .) ** 5` matches five such alternates. `$0` is the capture group for the outermost group. Since it is repeated, it will be a list of match objects. Each such match object will contain a capture group match object only if it's an uppercase letter.
* As for the replacement text, `flat('A'..'Z', ^6)` evaluates to a list of all uppercase letters followed by the numbers zero through five. The following bracketed expression is an index into that list, providing the replacement character for each set of five ID characters.
* `$0` is a list of match objects, one per character.
* `$0[4‚Ä¶0;0]` is a list of the submatch objects, in reverse order. For uppercase letters, this is a match object; for other characters, it's `Nil`.
* `?¬´` coerces that list of objects to boolean values. Match objects beome `True`, and `Nil` becomes `False`.
* `:2[...]` combines those binary/boolean digits into a number.
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~41~~ 37 bytes
```
{x,,/[`c$65+!26;$!6]@2/|+3 5#~"A["'x}
```
[Try it online!](https://ngn.bitbucket.io/k/#eJxdkF1LwzAUhu/Pr8hqwYtNGjMamIJ4XFvNauaYupshOOuyIdtAO3Dix2+3NGkh5718ePKS95iz70OvF82fi1DG3Y6Q52FHPl2K6KfbZ/HRX4Dz4PjwC2BYsODTlNdRo20xDiw71ZZJsZ2sasZb9m4mX/fOy9zbRH70M+tlA8f4QHwK6/mpGb4MX1NzvVZv+Ubv7qx3VSSpWd2oUX6rxxWDCPbLcs+KRbksgXyVVTm5YIRqfAAgA1rTowoVkFVOJFThI5CpbaNHNU6B7G8afZojAjlK0+gHK5FcyomEzvIZkPM1jT7lIoZ/Jn2Khw==)
* `~"A["'x` generate a bit mask indicating which values of `x` (the input) are uppercase letters
* `|+3 5#` chunk the input into five-length sections, transposing them and reversing the result to set up for...
* `2/` converting each column from a list of base-two values to a single base-ten number
* `,/[`c$65+!26;$!6]@` generate `"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"` and index into it with the above
* `x,` append the checksum to the input (and implicitly return)
[Answer]
# [BQN](https://mlochbaum.github.io/BQN/), 40 bytes[SBCS](https://github.com/mlochbaum/BQN/blob/master/commentary/sbcs.bqn)
```
{ùï©‚àæ(u‚àæu-17)‚äèÀú2‚ä∏√ó‚ä∏+Àú¬¥¬®(5/‚Üï3)‚äîùï©‚àäu‚Üê'A'+‚Üï26}
```
[Run online!](https://mlochbaum.github.io/BQN/try.html#code=RiDihpAge/CdlaniiL4odeKIvnUtMTcp4oqPy5wy4oq4w5fiirgry5zCtMKoKDUv4oaVMyniipTwnZWp4oiKdeKGkCdBJyvihpUyNn0KCuKImOKAvzLigL8x4qWKPuKLiOKfnEbCqCDin6gKImEwMU0wMDAwMDA2Mm1QZyIKIjAwMU0wMDAwMDBxZlB5UyIKImEwRkUwMDAwMDBENnIzRiIKIjBGOUUwMDAwMDAwOTJ3MiIKImFhYWFhYWFhYWFhYWFhYSIKIkFiQ2RFZkdoSWpLbE1uTyIKImFCY0RFZmdISUpLTE1OTyIK4p+p)
Or 31 bytes in [dzaima/BQN](https://github.com/dzaima/BQN):
```
{ùï©‚àæ(2‚ä∏√ó‚ä∏+Àú¬¥¬®(5/‚Üï3)‚äîùï©‚àä‚Ä¢a)‚äè‚Ä¢a‚àæ‚Ä¢d}
```
[Answer]
Dyalog APL, 23 bytes
```
{‚çµ,‚éïA[1+2‚ä•‚çâ‚éïA‚àä‚ç®‚åΩ3 5‚ç¥‚çµ]}
```
This is a straightforward mapping of the problem statement.
```
3 5‚ç¥‚çµ ‚çù Reshape the vector into a matrix of
      ‚çù 3 rows by 5 columns.
‚åΩ     ‚çù Reverse the rows.
‚éïA‚àä‚ç®  ‚çù For each element, check whether they
      ‚çù are a member(‚àä) of the uppercase
      ‚çù alphabet, ‚éïA.
2‚ä•‚çâ   ‚çù Decode, ‚ä•, the columns as a base 2
      ‚çù number. The transpose, ‚çâ, is so the
      ‚çù rows becomes the columns. The result
      ‚çù is a three element vector.
1+    ‚çù Add one to each element so that they
      ‚çù map to the indexes of the letters on
      ‚çù the alphabet. This is because arrays
      ‚çù in APL are 1 indexed by default. 
‚éïA[]  ‚çù Maps the indexes to their
      ‚çù corresponding uppercase letter.
‚çµ,    ‚çù Finally concatenate the original
      ‚çù vector with the result.
```
[Answer]
# [Canvas](https://github.com/dzaima/Canvas), 31 [bytes](https://github.com/dzaima/Canvas/blob/master/files/chartable.md)
```
ÔºïÔΩéÔΩõ¬±ÔΩõ‚îêÔº∫ÔΩõ¬≤‚â°ÔºΩ‚àëÔºΩÔºí‚î¥‚ïµÔºàÔº∫‚óÇÔºªÔºΩÔºñÔº†Ôºâ‚àëÔº†ÔºΩ‚§¢‚ï∂ÔºõÔºã
```
[Try it here!](https://dzaima.github.io/Canvas/?u=JXVGRjE1JXVGRjRFJXVGRjVCJUIxJXVGRjVCJXUyNTEwJXVGRjNBJXVGRjVCJUIyJXUyMjYxJXVGRjNEJXUyMjExJXVGRjNEJXVGRjEyJXUyNTM0JXUyNTc1JXVGRjA4JXVGRjNBJXUyNUMyJXVGRjNCJXVGRjNEJXVGRjE2JXVGRjIwJXVGRjA5JXUyMjExJXVGRjIwJXVGRjNEJXUyOTIyJXUyNTc2JXVGRjFCJXVGRjBC,i=YTBSRTAwMDAwMElKbWNO,v=8)
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, 63 bytes
```
map{y/A-Z/0/c;y/A-Z/1/;$\.=(A..Z,0..5)[oct"0b".reverse]}/.{5}/g
```
[Try it online!](https://tio.run/##K0gtyjH9/z83saC6Ut9RN0rfQD/ZGsIy1LdWidGz1XDU04vSMdDTM9WMzk8uUTJIUtIrSi1LLSpOja3V16s2rdVP//8/0SDI1QAMPL1yk/3@5ReUZObnFf/X9TXVMzA0@K9bAAA "Perl 5 ‚Äì Try It Online")
]