Relatively good tutorial is here. Using it, you'll get the next decomposition:
16i
- the input will be hexadecimal (like in bc
- ibase=16
)
[q]
- the [..]
mean string. So this store a string q
to the top of stack. Usually the [....]
is a series of commands stored for later execution (like a macro), in this case the command q
- quit.
- the
s
- take the top of stack and store it to register identified by the next letter, so the [q]sa
together in this case mean: store the the string q
into register a
- same with the next, store the string
ln0=aln100%Pln100/snlbx
into register b
- the next
A0D68736142sn
, store the A0D68736142
into register n
. In this case not a string, but because we have input hexaadecimal, this is an hexadecimal number
The above is an like a preparation phase, translated into common programming language:
$a = "q";
$b = "ln0=aln100%Pln100/snlbx";
$n = 0xA0D68736142";
The stack is now empty (everything is stored in registres).
The next is the final calculation:
- the
l
mean take the the the value from the followed register, and put it to the top of stack so the lb
mean: take the value of register b
.
- the
x
mean: execute it as an series of commands - in this case read it as eval "$b";
- the last
q
mean quit
now need decompose the ln0=aln100%Pln100/snlbx
(content of register b
- what is eval-ing.)
ln
- as above, take the value from the register n
in our case: the hexa-number
- next is a tricky part:
0=a
, take the top of stack, and if it is zero
execute the string (macro) stored in the registry "a" (in our case this is a "q" - quit), e.g. like:
if( $n == 0 ) eval "a"; #a contains "q" = quit
- if the
$n
isn't zero, take the content of regsiter n
again (ln
) (put to the top of stack)
- put the number
100
(it is hexa) to to top of stack
%
modulo the two numbers from the top of the stack (so: $n % 0x100
) and put it to the top of the stack
- print the top of stack as an ascii string (
chr($stack)
)
ln
take again the number $n
(again, it comes to the top of stack)
- put
100
to the stack
/
divide the to numbers in the stack (result comes into the top)
sn
store the stack into the $n
(replaces the original number)
lbx
- as above - eval the register b
So, in short:
- from the number
0xA0D68736142
stored in $n
,
- modulo it by
0x100
get the last two digits, convert it to ascii and print it,
- divide it by
0x100
(removes last two digits) - and store it to $n
- repeat until nothing remained (zero)
For the 0xA0D68736142
you will get (use man ascii
)
42
- B
61
- a
73
- s
68
- h
0D
- \r
A
(as 0A) - \n
Creating such hexsting from normal ascii string with perl
perl -E '$s=reverse("Bash\r\n");$s =~ s/(.)/sprintf("%02x",ord($1))/seg;say uc $s'
prints
0A0D68736142
or
perl -E '$s=reverse("Stackoverflow rocks\n");$s =~ s/(.)/sprintf("%02x",ord($1))/seg;say uc $s'
0A736B636F7220776F6C667265766F6B63617453
and
echo "16i[q]sa[ln0=aln100%Pln100/snlbx]sb0A736B636F7220776F6C667265766F6B63617453snlbxq" | dc
prints:
Stackoverflow rocks
Ps: with dc
is one strange thing - it is much-much easier to read and understand a "program" as creating one. :)