#!/bin/bash set -u declare -A ord_hash # associative hash; requires Bash version 4 function init_urlencode() { # this is the whole ASCII set, without the chr(0) and chr(255) characters ASCII='  !"#$%&'\''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' # chr(0) cannot be stored in a Bash variable local idx for idx in {0..253}; do # 0..253 = 254 elements = length($ASCII) local c="${ASCII:$idx:1}" # VERY SLOW local store_idx=$(($idx+1)) ord_hash["$c"]="$store_idx" # chr(255) cannot be used as a key done } function urlencode() { local inp="$1" local len="${#inp}" local n=0 local val while [ "$n" -lt "$len" ]; do local c="${inp:$n:1}" # VERY SLOW if [ "$c" == "" ]; then # chr(255) cannot be used as a key val=255 else val="${ord_hash[$c]}" fi printf '%%%02X' "$val" n=$((n+1)) done } init_urlencode # call only once urlencode 'some^fancy#text'