Substitution cipher: Difference between revisions

Content added Content deleted
(add Risc-V solution)
(→‎{{header|Risc-V}}: RISC-V: Cleaned up the solution a bit)
Line 2,090: Line 2,090:
<syntaxhighlight lang="risc-v">
<syntaxhighlight lang="risc-v">
# gnu assembler syntax
# gnu assembler syntax
substitution_cipher: # char* str (a0), uint len (a1), const char lowerkey[26] (a2), const char upperkey[26] (a3)
lcipher: .ascii "zyxwvutsrqponmlkjihgfedcba"
# set up temporary registers t0, t1, t2, t3
ucipher: .ascii "ZYXWVUTSRQPONMLKJIHGFEDCBA"
substitution_cipher: # (a0: char* str) (a1: uint len)
# set up temporary registers t0, t1, t3, t4
li t0, 'a
li t0, 'a
li t1, 'z
li t1, 'z
li t3, 'A
li t2, 'A
li t4, 'Z
li t3, 'Z
lui t5, %hi(lcipher)
# char tmp (t4)
lui t6, %hi(ucipher)
# char* cipher (t5)


.dcB: # begin loop
.dcB: # begin loop
beqz a1, .dcE # break condition
beqz a1, .dcE # break condition
lb t2, 0(a0) # load one character from a0
lb t4, 0(a0) # load one character from a0
blt t2, t0, .dcU # lowercase check
blt t4, t0, .dcU # lowercase check
bgt t2, t1, .dcA
bgt t4, t1, .dcI
addi t2, t2, -'a
addi t4, t4, -'a
addi a5, t5, %lo(lcipher)
mv t5, a2
j .dcA
j .dcA
.dcU: # uppercase check
.dcU: # uppercase check
blt t2, t3, .dcI
blt t4, t2, .dcI
bgt t2, t4, .dcI
bgt t4, t3, .dcI
addi t2, t2, -'A
addi t4, t4, -'A
addi a5, t6, %lo(ucipher)
mv t5, a3
.dcA: # convert and save ciphertext character
.dcA: # convert and save ciphertext character
add a5, a5, t2
add t5, t5, t4
lb a5, 0(a5)
lb t5, 0(t5)
sb a5, 0(a0)
sb t5, 0(a0)
.dcI: # increment registers
.dcI: # increment registers
addi a1, a1, -1
addi a1, a1, -1
addi a0, a0, 1
addi a0, a0, 1
j .dcB
j .dcB
.dcE: # end loop
.dcE: ret # end loop

ret
# You can use the following cipher keys, which correspond to the Atbash cipher,
# to test the substitution. These keys are self-inverse, which means that
# applying them twice to a given plaintext yields the original plaintext again.
latbash: .ascii "zyxwvutsrqponmlkjihgfedcba"
uatbash: .ascii "ZYXWVUTSRQPONMLKJIHGFEDCBA"

# For keys that are non-self-inverse, you will need to keep a separate set of
# encryption and decryption keys.
lzebras: .ascii "zebrascdfghijklmnopqtuvwxy"
uzebras: .ascii "ZEBRASCDFGHIJKLMNOPQTUVWXY"
ldzebras: .ascii "ecghbijklmnopqrstdfuvwxyza"
udzebras: .ascii "ECGHBIJKLMNOPQRSTDFUVWXYZA"
</syntaxhighlight>
</syntaxhighlight>