11#! /usr/bin/env bash
22
3+ # -e: exit immediately if a command exits with a non-zero status
4+ # -u: treat unset variables as an error and exit immediately
5+ # -C: prevent overwriting files
6+ set -euC
7+
38readonly DEFAULT_ALPHABET=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
49readonly DEFAULT_BLOCKLIST=(
510 " 0rgasm"
@@ -567,61 +572,63 @@ readonly DEFAULT_MIN_LENGTH=0
567572
568573# usage: ord "A" -> 65
569574ord () {
570- printf -v retval " %d" " '$1 "
575+ printf -v __RETURN " %d" " '$1 "
571576}
572577
573578# usage: splitstr "abcde" -> "a b c d e"
574579splitstr () {
575580 local s=" $1 "
581+ local i
576582 arr=()
577- for (( i_splitstr = 0 ; i_splitstr < ${# s} ; i_splitstr ++ )) ; do
578- arr+=(" ${s: $i_splitstr : 1} " )
583+ for (( i = 0 ; i < ${# s} ; i ++ )) ; do
584+ arr+=(" ${s: $i : 1} " )
579585 done
580586
581- retval =${arr[*]}
587+ __RETURN =${arr[*]}
582588}
583589
584590# usage: joinchars "," a b c d e -> "a,b,c,d,e"
585591joinchars () {
586592 local separator=$1
587593 local str=" "
588- for (( i_joinchars = 2 ; i_joinchars < $# ; i_joinchars++ )) ; do
589- str+=" ${! i_joinchars} "
594+ local i
595+ for (( i = 2 ; i < $# ; i++ )) ; do
596+ str+=" ${! i} "
590597 str+=" $separator "
591598 done
592599 str+=" ${!# } "
593600
594- retval =" $str "
601+ __RETURN =" $str "
595602}
596603
597604# usage: lower "AbCdE" -> "abcde"
598605lower () {
599- retval =" ${1,,} "
606+ __RETURN =" ${1,,} "
600607}
601608
602609# usage: shuffle "abcdefg" -> "bcefgad"
603610shuffle () {
604611 local alphabet=" $1 "
605612 splitstr " $alphabet "
606613 local chars
607- IFS=" " read -r -a chars <<< " $retval "
614+ IFS=" " read -r -a chars <<< " $__RETURN "
608615 local len=${# alphabet}
609- local i_shuffle =0
610- local j_shuffle =$(( len - 1 ))
611-
612- while [ $j_shuffle -gt 0 ]; do
613-
614- ord " ${chars[i_shuffle ]} "
615- local i_shuffle_ord= $retval
616- ord " ${chars[j_shuffle ]} "
617- local j_shuffle_ord= $retval
618-
619- local r_shuffle =$(( (i_shuffle * j_shuffle + i_shuffle_ord + j_shuffle_ord ) % len))
620- local temp=${chars[$i_shuffle ]}
621- chars[i_shuffle ]=${chars[$r_shuffle ]}
622- chars[r_shuffle ]=$temp
623- i_shuffle =$(( i_shuffle + 1 ))
624- j_shuffle =$(( j_shuffle - 1 ))
616+ local i =0
617+ local j =$(( len - 1 ))
618+
619+ while [ $j -gt 0 ]; do
620+
621+ ord " ${chars[i ]} "
622+ local i_ord= $__RETURN
623+ ord " ${chars[j ]} "
624+ local j_ord= $__RETURN
625+
626+ local r =$(( (i * j + i_ord + j_ord ) % len))
627+ local temp=${chars[$i ]}
628+ chars[i ]=${chars[$r ]}
629+ chars[r ]=$temp
630+ i =$(( i + 1 ))
631+ j =$(( j - 1 ))
625632 done
626633
627634 joinchars " " " ${chars[@]} "
@@ -652,7 +659,7 @@ to_number() {
652659 local count=${# alphabet}
653660
654661 splitstr " $id "
655- for id_char in $retval ; do
662+ for id_char in $__RETURN ; do
656663 local index
657664 for (( index = 0 ; index < count; index++ )) ; do
658665 if [ " ${alphabet: $index : 1} " == " $id_char " ]; then
@@ -662,15 +669,15 @@ to_number() {
662669 result=$(( result * count + index))
663670 done
664671
665- retval =$result
672+ __RETURN =$result
666673}
667674
668675# usage: is_blocked_id "blockedword1 blockedword2 blockedword3" "abcde" -> false
669676is_blocked_id () {
670677 local block_list=$1
671678 local id=" $2 "
672679 lower " $id "
673- id=$retval
680+ id=$__RETURN
674681
675682 for word in $block_list ; do
676683 if [ ${# word} -gt ${# id} ]; then
@@ -679,21 +686,21 @@ is_blocked_id() {
679686
680687 if [[ ${# id} -le 3 || ${# word} -le 3 ]]; then
681688 if [ " $id " == " $word " ]; then
682- retval =true
689+ __RETURN =true
683690 return 0
684691 fi
685692 elif [[ " $word " == * [0-9]* ]]; then
686693 if [[ " $id " == " $word " * || " $id " == * " $word " ]]; then
687- retval =true
694+ __RETURN =true
688695 return 0
689696 fi
690697 elif [[ " $id " == * " $word " * ]]; then
691- retval =true
698+ __RETURN =true
692699 return 0
693700 fi
694701 done
695702
696- retval =false
703+ __RETURN =false
697704 return 0
698705}
699706
@@ -702,6 +709,7 @@ encode_numbers() {
702709 local original_alphabet_str
703710 local block_list
704711 local min_length
712+ local i
705713
706714 local OPTIND=0
707715 while getopts a:b:l: OPT; do
@@ -717,7 +725,7 @@ encode_numbers() {
717725 done
718726
719727 shuffle " $original_alphabet_str "
720- local alphabet_str=$retval
728+ local alphabet_str=$__RETURN
721729
722730 shift $(( OPTIND - 1 ))
723731
@@ -735,7 +743,7 @@ encode_numbers() {
735743 local v=${numbers[i]}
736744 local char=${alphabet_str: $((v % ${# alphabet_str} )): 1}
737745 ord " $char "
738- local char_ord=$retval
746+ local char_ord=$__RETURN
739747 offset=$(( offset + char_ord + i))
740748 done
741749
@@ -765,33 +773,33 @@ encode_numbers() {
765773 for (( i = 0 ; i < ${# numbers[@]} ; i++ )) ; do
766774 local num=${numbers[$i]}
767775 to_id " $num " " ${alphabet_str: 1} "
768- ret+=(" $retval " )
776+ ret+=(" $__RETURN " )
769777
770778 if [[ $i -ge $(( ${# numbers[@]} - 1 )) ]]; then
771779 continue
772780 fi
773781
774782 ret+=(" ${alphabet_str: 0: 1} " )
775783 shuffle " $alphabet_str "
776- alphabet_str=$retval
784+ alphabet_str=$__RETURN
777785 done
778786
779787 joinchars " " " ${ret[@]} "
780- local id=$retval
788+ local id=$__RETURN
781789
782790 if [ " $min_length " -gt " ${# id} " ]; then
783791 id+=${alphabet_str: 0: 1}
784792
785793 while [ $(( min_length - ${# id} )) -gt 0 ]; do
786794 shuffle " $alphabet_str "
787- alphabet_str=$retval
795+ alphabet_str=$__RETURN
788796 joinchars " " " ${alphabet_str: 0: $((min_length - ${# id} < ${# alphabet_str} ? min_length - ${# id} : ${# alphabet_str} ))} "
789- id+=$retval
797+ id+=$__RETURN
790798 done
791799 fi
792800
793801 is_blocked_id " $block_list " " $id "
794- local is_blocked=$retval
802+ local is_blocked=$__RETURN
795803 if $is_blocked ; then
796804 encode_numbers -a " $original_alphabet_str " -b " $block_list " -l " $min_length " " ${numbers[@]} " $(( increment + 1 ))
797805 else
@@ -823,13 +831,18 @@ encode() {
823831 if [[ -z " $* " ]]; then
824832 echo " "
825833 else
826- encode_numbers -a " $alphabet " -b " $block_list " -l " $min_length " " $@ " 0
834+ nums=()
835+ for num in " $@ " ; do
836+ nums+=(" $(( 10 #$num )) " )
837+ done
838+ encode_numbers -a " $alphabet " -b " $block_list " -l " $min_length " " ${nums[@]} " 0
827839 fi
828840}
829841
830842# usage: decode -a $DEFAULT_ALPHABET "abcde" -> 10273415
831843decode () {
832844 local alphabet_str
845+ local i
833846
834847 local OPTIND=0
835848 while getopts :a: OPT; do
@@ -843,7 +856,7 @@ decode() {
843856 done
844857
845858 shuffle " $alphabet_str "
846- alphabet_str=$retval
859+ alphabet_str=$__RETURN
847860
848861 shift $(( OPTIND - 1 ))
849862
@@ -857,10 +870,10 @@ decode() {
857870
858871 # check if any characters are not in the alphabet
859872 splitstr " $id "
860- for c in $retval ; do
873+ for c in $__RETURN ; do
861874 local does_exist=false
862875 splitstr " $alphabet_str "
863- for a in $retval ; do
876+ for a in $__RETURN ; do
864877 if [ " $a " == " $c " ]; then
865878 does_exist=true
866879 break
@@ -894,7 +907,7 @@ decode() {
894907 done
895908
896909 joinchars " " " ${alphabet_chars_rev[@]} "
897- alphabet_str=$retval
910+ alphabet_str=$__RETURN
898911
899912 id=" ${id: 1} "
900913
@@ -920,18 +933,18 @@ decode() {
920933 return 0
921934 else
922935 to_number " ${chunks[0]} " " ${alphabet_str: 1: ${# alphabet_str} -1} "
923- ret+=(" $retval " )
936+ ret+=(" $__RETURN " )
924937
925938 if [ " ${# chunks[@]} " -gt 1 ]; then
926939 shuffle " $alphabet_str "
927- alphabet_str=$retval
940+ alphabet_str=$__RETURN
928941 fi
929942 fi
930943 fi
931944
932945 if [ " ${# chunks[@]} " -gt 1 ]; then
933946 joinchars " $separator " " ${chunks[@]: 1} "
934- id=$retval
947+ id=$__RETURN
935948 else
936949 echo " ${ret[@]} "
937950 return 0
@@ -974,6 +987,10 @@ main() {
974987 local min_length=" $DEFAULT_MIN_LENGTH "
975988 local alphabet=" $DEFAULT_ALPHABET "
976989 local block_list=" ${DEFAULT_BLOCKLIST[*]} "
990+ local flag_a=false
991+ local flag_b=false
992+ local flag_e=false
993+ local flag_d=false
977994
978995 local OPTIND=0
979996 while getopts :a:b:l:edhv OPT; do
@@ -1011,15 +1028,15 @@ main() {
10111028 exit 1
10121029 fi
10131030
1014- if [[ $flag_e && $flag_d ]] ; then
1031+ if $flag_e && $flag_d ; then
10151032 echo " ERROR: option -e (encode) and -d (decode) cannot be used together" >&2
10161033 exit 1
10171034 fi
10181035
10191036 splitstr " $alphabet "
1020- for char in $retval ; do
1037+ for char in $__RETURN ; do
10211038 ord " $char "
1022- local char_ord=$retval
1039+ local char_ord=$__RETURN
10231040 if [[ $char_ord -gt 127 ]]; then
10241041 echo " ERROR: Alphabet cannot contain multibyte characters" >&2
10251042 exit 1
@@ -1045,20 +1062,20 @@ main() {
10451062 local filtered_blocklist=()
10461063 if $flag_a || $flag_b ; then
10471064 lower " $alphabet "
1048- local alphabet_lower=$retval
1065+ local alphabet_lower=$__RETURN
10491066 declare -A alphabet_lower_dict
10501067 splitstr " $alphabet_lower "
1051- for char in $retval ; do
1068+ for char in $__RETURN ; do
10521069 alphabet_lower_dict[$char ]=true
10531070 done
10541071
10551072 lower " $block_list "
1056- for word_lower in $retval ; do
1073+ for word_lower in $__RETURN ; do
10571074 if [[ ${# word_lower} -ge 3 ]]; then
10581075 local does_exist=true
10591076 splitstr " $word_lower "
1060- for char in $retval ; do
1061- if [[ -z " ${alphabet_lower_dict[$char]} " ]]; then
1077+ for char in $__RETURN ; do
1078+ if [[ -z " ${alphabet_lower_dict[$char]:- false } " ]]; then
10621079 does_exist=false
10631080 break
10641081 fi
0 commit comments