Konvertieren Sie eine Salesforce-ID mit 15 Zeichen in eine ID mit 18 Zeichen

20

In Salesforce CRM hat jedes Objekt eine alphanumerische ID mit 15 Zeichen, bei der zwischen Groß- und Kleinschreibung unterschieden wird. Wenn jemand neugierig ist, ist es tatsächlich die Basis-62-Nummer . Für die Datenmigration und -integration verwendete Tools unterstützen jedoch möglicherweise die Groß- und Kleinschreibung. Um dies zu vermeiden, können IDs sicher in alphanumerische IDs konvertiert werden, bei denen die Groß- und Kleinschreibung keine Rolle spielt. Dabei wird an die ID eine 3-stellige alphanumerische Prüfsumme angehängt. Der Konvertierungsalgorithmus lautet:

Beispiel :

a0RE000000IJmcN
  1. Teilen Sie die ID in drei 5-stellige Blöcke auf.

    a0RE0  00000  IJmcN
    
  2. Kehre jeden Brocken um.

    0ER0a  00000  NcmJI
    
  3. Ersetzen Sie jedes Zeichen in jedem Block durch 1Großbuchstaben oder durch 0andere.

    01100  00000  10011
    
  4. Ermitteln Sie für jede 5-stellige Binärzahl idas Zeichen an der Position iin der Verkettung von Großbuchstaben und Ziffern 0-5 ( ABCDEFGHIJKLMNOPQRSTUVWXYZ012345).

    00000 -> A,
    00001 -> B,
    00010 -> C, ..., 
    11010 -> Z, 
    11011 -> 0, ...,
    11111 -> 5`
    

    Ausbeute:

    M  A  T
    
  5. Hängen Sie diese Zeichen, die Prüfsumme, an die ursprüngliche ID an.

Ausgabe :

a0RE000000IJmcNMAT

Schreiben Sie ein Programm oder eine Funktion, die eine 15-stellige alphanumerische Zeichenfolge (ASCII) als Eingabe verwendet und eine 18-stellige ID zurückgibt.

Die Eingabevalidierung ist von dieser Frage ausgeschlossen. Programme können bei ungültiger Eingabe einen beliebigen Wert zurückgeben oder abstürzen.

Bitte verwenden Sie keine Salesforce propretiary Sprachen Funktionen , die diese Herausforderung trivial (wie Formel machen CASESAFEID(), die Umwandlung Idzu Stringin APEX & c).

Testfälle

a01M00000062mPg    -> a01M00000062mPgIAI
001M000000qfPyS    -> 001M000000qfPySIAU
a0FE000000D6r3F    -> a0FE000000D6r3FMAR
0F9E000000092w2    -> 0F9E000000092w2KAA
aaaaaaaaaaaaaaa    -> aaaaaaaaaaaaaaaAAA
AbCdEfGhIjKlMnO    -> AbCdEfGhIjKlMnOVKV
aBcDEfgHIJKLMNO    -> aBcDEfgHIJKLMNO025
Trang Oul
quelle
3
Leider wäre die Konvertierung einer Zeichenfolge in eine ID in Apex-Code immer noch nicht kürzer als einige der hier angegebenen Antworten, insbesondere wenn der Code in sich geschlossen sein muss. Apex Code ist nicht gut zum Golfen geeignet.
Phyrfox
2
@phyrfox als ehemaliger Salesforce-Entwickler Apex ist nicht für viel geeignet ...
Mike McMahon
2
APEX, 56 Bytes public class X{public X(Id i){System.debug((String)i);}}. Funktioniert jedoch nur mit gültigen Salesforce-IDs.
Trang Oul
Ich bin hierher gekommen, um dies aus beruflichen Gründen zu tun ( success.jitterbit.com/display/DOC/… ) , nicht um Golf zu spielen, aber ich bin ein wenig verwirrt über die Beschreibung des Algorithmus. Sie sagen, dass jeder umgedrehte und bereinigte Block in Schritt 4 eine "Binärzahl" ist, aber Sie ersetzen die Ziffern 2 bis 8 niemals durch Nullen und Einsen. Was genau soll ich für Schritt 4 tun, wenn die Schritte 1-3 für einen Block wie "62mPg" zu einer Zahl wie "01026" geführt haben?
k ..

Antworten:

6

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

Dieser hat ein paar wirklich nette Tricks.

Mein ursprünglicher Instinkt für die Aufteilung der Saite in Gruppen von 5 Zeichen war 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]]

Es stellt sich heraus, dass dies im Vergleich zu einer einfachen Regex ( x.chars.each_slice(5)vs. x.scan(/.{5}/)) zu lange dauert . Dies scheint im Nachhinein offensichtlich, aber ich habe nie wirklich darüber nachgedacht ... Vielleicht kann ich hier einige meiner alten Ruby-Antworten optimieren.

Das, worauf ich in dieser Antwort am meisten stolz bin, ist der folgende Code:

y=~/[^A-Z]/||1

Okay, hier ist ein Hintergrund für die Nicht-Rubyisten. Ruby trennt Boolesche Werte ( TrueClass, FalseClass) vollständig von Ganzzahlen / Zahlen ( Numeric). Dies bedeutet, dass es auch keine automatische Konvertierung von true nach 1 und false nach 0 gibt. Dies ist beim Golfen ärgerlich (aber eine gute Sache ... für alle anderen Zwecke).

Der naive Ansatz zum Überprüfen, ob ein einzelnes Zeichen in Großbuchstaben geschrieben ist (und 1 oder 0 zurückgibt) ist

y.upcase==y?1:0

Wir können dies ein wenig weiter unten (wieder mit einem regulären Ausdruck):

y=~/[A-Z]/?1:0

Aber dann habe ich wirklich nachgedacht. Hmm ... =~gibt den Index einer Übereinstimmung (also für unser einzelnes Zeichen immer, 0wenn es eine Übereinstimmung gibt) oder nilbei Nichtübereinstimmung einen falschen Wert zurück (alles andere außer FalseClassist in Ruby wahr). Der ||Operator nimmt seinen ersten Operanden, wenn er wahr ist, und seinen zweiten Operanden, wenn er wahr ist. Daher können wir dies bis auf Golf spielen

y=~/[^A-Z]/||1

Okay, schauen wir uns an, was hier passiert. Wenn yes sich um einen Großbuchstaben handelt, [^A-Z]stimmt dieser nicht überein , sodass der reguläre Ausdruck zurückgegeben wird nil. nil || 1ist 1, so werden Großbuchstaben 1. Wenn yalles andere als ein Großbuchstabe, kehrt der regex Teil 0(weil es eine Übereinstimmung mit dem Index ist 0), und da 0truthy ist, 0 || 1ist 0.

... und erst nachdem ich das alles ausgeschrieben habe, merke ich, dass dies tatsächlich die gleiche Länge ist wie y=~/[A-Z]/?1:0. Haha, na ja.

Türknauf
quelle
6

Pyth, 23 22 Bytes

1 Byte von FryAmTheEggman gespeichert .

sm@s+JrG1U6i}RJ_d2c3pz

Probieren Sie es online aus. Testsuite.

Dies könnte das erste Mal sein, dass ich die pRint-Anweisung beim Golfen verwendet habe.

Erläuterung

     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
PurkkaKoodari
quelle
4

MATL , 24 Bytes

j1Y24Y2hG5IePtk=~!XB1+)h

Verwendet die aktuelle Version (9.1.0) der Sprache / des Compilers.

Beispiele

>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a0RE000000IJmcN
a0RE000000IJmcNMAT

>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a01M00000062mPg
a01M00000062mPgIAI

Erläuterung

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
Luis Mendo
quelle
3

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

Prüfung

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>

edc65
quelle
2

CJam, 27 Bytes

l_5/{W%{_el=!}%2bH+43%'0+}%

Führen Sie alle Testfälle aus.

Eine ziemlich einfache Implementierung der Spezifikation. Der interessanteste Teil ist die Umwandlung in Zeichen in der Prüfsumme. Wir addieren 17 zum Ergebnis jedes Blocks. Nehmen Sie das Modulo 43 und fügen Sie das Ergebnis dem Charakter hinzu '0.

Martin Ender
quelle
2

Japt, 46 Bytes

U+U®f"[A-Z]" ?1:0} f'.p5)®w n2 +A %36 s36 u} q

Mit der Länge nicht allzu zufrieden, aber ich finde keinen Weg, um Golf zu spielen. Probieren Sie es online!

ETHproductions
quelle
2

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 gespart dank @ ՊՓԼՃՐՊՃՈԲՍԼ !

Erläuterung

Diese Herausforderung ist überhaupt nicht für JavaScript geeignet. Es gibt keine kurze Möglichkeit, eine Zeichenfolge umzukehren, und es sieht so aus, als ob die kürzeste Möglichkeit, die Zahl in ein Zeichen umzuwandeln, darin besteht, jedes mögliche Zeichen hart zu codieren.

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``

Wenn die Ziffern in der Prüfsumme in Kleinbuchstaben angegeben werden dürfen, kann dies in 124 Bytes erfolgen:

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``

Prüfung

user81655
quelle
Wenn ich mich nicht irre, parseInt([...n].reverse().join``,2)könnte zu geändert werden +`0b${[...n].reverse().join``}`.
Mama Fun Roll
@ ՊՓԼՃՐՊՃՈԲՍԼ Richtig, du bist! Ich habe auch noch ein weiteres Byte gespeichert, danke.
user81655
Speichern Sie 10 ganze Bytes mit .replace(/.{5}/g,n=>/*stuff*/).
Neil
2

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)])

Als Eingabe wird ein String abgefragt und die Ausgabe auf dem Bildschirm angezeigt.

Erläuterung

Ich benutze hier wahrscheinlich den einfachsten Ansatz:

  • Eingabe anfordern
  • Umformen auf 5 (Zeilen) x 3 (Spalten)
  • Drehe die Zeilenreihenfolge um
  • Transponieren Sie die Matrix, um sie für das Lesen als Binärdatei vorzubereiten
  • Ordnen Sie das Array ABC ... XYZ012345 zu
  • Vergleichen Sie die Zeichenindizes der transponierten Matrix mit ihrem Äquivalent in Kleinbuchstaben und konvertieren Sie die Booleschen Werte in Zeichenfolgen, die dann als binär gelesen und in Dezimalzahlen konvertiert werden.
  • Interpretieren Sie diese Dezimalstellen (inkrementiert um 1) als Indizes des zugewiesenen Arrays.
  • Zeigen Sie die Eingabe mit den zusätzlichen 3 Zeichen an

Jetzt unter 100 Bytes dank Luis Mendo!

slvrbld
quelle
1
Mite=['A':'Z',48:53]
Luis Mendo
Ich sehe, mein Ansatz ist fast das gleiche wie bei Ihnen :-)
Luis Mendo
2

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;

Ungeplündert

<?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;

Ich begann zu denken, ich könnte es viel kürzer machen, aber mir gingen die Ideen aus, um es kürzer zu machen.

Samsquanch
quelle
1

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])
TFeld
quelle
1

PowerShell, 162 Byte

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, in diesem passiert eine Menge ordentliches Zeug. Ich werde mit der zweiten Zeile beginnen.

Wir nehmen die Eingabe als String über $args[0]und setzen sie $afür die spätere Verwendung. Dies ist so gekapselt, ()dass es ausgeführt und das Ergebnis zurückgegeben wird (dh $a), sodass wir es sofort mit den Ergebnissen von drei Funktionsaufrufen verketten können (f ...). Jeder Funktionsaufruf als Argument übergibt die Eingabezeichenfolge in umgekehrter Reihenfolge Chunks als char-Array indiziert - das heißt, für den Beispiel - Eingang, $a[4..0]wird gleich @('0','E','R','0','a')mit jedem Eintrag als char, kein String.

Nun zur Funktion, wo das eigentliche Fleisch des Programms ist. Wir nehmen Eingaben als $f, aber sie werden erst gegen Ende verwendet. Konzentrieren wir uns also zuerst darauf. Da es als char-Array übergeben wurde (dank unserer vorherigen Indizierung), können wir es sofort in eine Schleife mit leiten $f|%{...}. Innerhalb der Schleife nehmen wir jedes Zeichen und führen eine Regex-Übereinstimmung durch, bei -cmatchder zwischen Groß- und Kleinschreibung unterschieden wird. Wir setzen das als Ganzzahl mit der Einkapselung um +(), dann wird dieses Array aus Einsen und -joinNullen zu einer Zeichenfolge verarbeitet. Dies wird dann als erster Parameter im .NET- [convert]::ToInt32()Aufruf übergeben, um die Binärzahl (Basis 2) in eine Dezimalzahl zu ändern . Wir verwenden diese resultierende Dezimalzahl, um eine Zeichenfolge zu indizieren (-join(...)[...]). Die Zeichenfolge wird zuerst als Bereich formuliert (65..90), der als Zeichen-Array umgewandelt und dann mit dem Bereich verkettet wird (0..5)(dh die Zeichenfolge ist "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"). Das heißt, Sie geben das entsprechende Zeichen aus der Zeichenfolge zurück.

AdmBorkBork
quelle
1

Jolf, 30 Bytes

Endlich ein wohl noch jolfbarer! Probieren Sie es hier aus!

+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"
Conor O'Brien
quelle
1

Python 3, 201 174 138 Bytes

Ein großes Dankeschön an Trang Oul für den Hinweis auf eine Funktionsdeklaration, die es nicht mehr geben musste. Und ternäre Python-Operatoren. Und eine falsche Ausgabe. Gib ihm nur die Gegenstimmen.

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)
Steve Eckert
quelle
Wenn Sie die Funktion z()einmal verwenden, können Sie ihren Aufruf ersetzen und 25 Bytes sparen. Außerdem weist Ihr Code statt falsch [zu 0.
Trang Oul
Nun, das war für mich ein peinliches Versehen. Vielen Dank.
Steve Eckert
1
Sie können zunächst durch den Austausch noch mehr sparen if elsemit dieser Konstruktion mit ternärem Operator und zweiten.
Trang Oul
1

J, 36 Bytes

,_5(u:@+22+43*<&26)@#.@|.\]~:tolower

Verwendung:

   (,_5(u:@+22+43*<&26)@#.@|.\]~:tolower) 'a0RE000000IJmcN'
a0RE000000IJmcNMAT

Probieren Sie es hier online aus.

randomra
quelle
1

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);}}

Funktioniert für jede Eingabe, deren Länge ein Vielfaches von 5 ist :)

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);
    }
}
Cole Cameron
quelle
Um ein paar Bytes zu sparen, können Sie n aus dem globalen Namespace entfernen, wenn Sie main (n, v, s) für Ihre Signatur verwenden, da Sie sonst argc nicht verwenden.
Cleblanc
Ersetzen Sie außerdem 26 * 17 durch
normales
Mit ein paar weiteren Änderungen konnte ich Ihre Version auf 110 Bytes reduzieren. Ich verstehe nicht, warum du !! isupprer () hattest, wenn isupper () für mich gut zu funktionieren scheint. Außerdem habe ich deine for-Schleifen {} j;main(n,v,s)char**v,*s;{for(printf(s=v[1]);*s;s+=5,putchar(n+65-n/442))for(n=0,j=5;j--;n=n*2+isupper(s[j]));}
überarbeitet
@cleblanc Ausgezeichnete Vorschläge, vielen Dank. Die Reihenfolge der Operationen ist für den n/26*17Ausdruck sehr wichtig , daher ist das Ersetzen durch 442 keine Option. Soweit !!isupperdiese Funktion auf meinem System nicht 1 für true zurückgibt, gibt sie 256 zurück. Dies !!ist eine kurze Möglichkeit, sie in einen 0/1-Rückgabewert zu konvertieren, egal was passiert . YMMV.
Cole Cameron
1

C # 171 Bytes

Ich bin nicht wirklich gut darin geübt, C # zu spielen, aber hier ist ein Schuss.

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;}
Cole Cameron
quelle
Vorschläge: char.IsUpper(t)können durch ersetzt werden t>=65&t<=90( &auf Bool in C # ist im Grunde ein Golf-Shorter &&ohne Kurzschluss). 447ist kürzer als 26*17. Sie müssen keine separate SelectAnweisung ausführen: Sie können das Ternär direkt in die Anweisung einschließen Sum. Ziehen Sie in Betracht, alle diese Verwendungen von Substringdurch eine Schleife zu ersetzen, die Takestattdessen auf basiert , z for(int i=0;i<3;i++)s.Skip(i*5).Take(5). Für zukünftige Referenz u!=""wäre kürzer als u.Length>0(aber das ist nicht mehr nötig, wenn Sie verwenden Take).
Bob
Der Ausdruck n/26*17ist nicht gleichbedeutend mit n/442, aber ansonsten danke für die Vorschläge. Wie gesagt, ich bin nicht sehr erfahren im Golfen in C #, daher ist das alles großartige Dinge, die ich in Zukunft in Betracht ziehen sollte.
Cole Cameron
Ah, tut mir leid - ich habe das falsch verstanden.
Bob
1

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;}

Auf Wunsch werde ich meinen Code wieder lesbar machen und veröffentlichen.

Yytsi
quelle
1

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))
Aleksi Torhamo
quelle