function _color_hash_djb2 { local c h s s=$1 h=${2:-5381} while (( ${#s} > 0 )); do c=0x${s%${s#??}} s=${s#??} h=$(( ((($h << 5) + $h) ^ $c) & 0xffff )) done print -nr -- $h } function _color_hash_fnv1 { local c h s s=$1 h=${2:-2166136261} while (( ${#s} > 0 )); do c=0x${s%${s#??}} s=${s#??} h=$(( (($h << 24) + ($h << 8) + ($h << 7) + ($h << 4) + ($h << 1) + $h) & 0xffffffff )) h=$(( $h ^ $c )) done # xor-fold to 16 bits print -nr -- $(( ($h >> 16) ^ ($h & 0xffff) )) } function _color_hash_fnv1a { local c h s s=$1 h=${2:-2166136261} while (( ${#s} > 0 )); do c=0x${s%${s#??}} s=${s#??} h=$(( $h ^ $c )) h=$(( (($h << 24) + ($h << 8) + ($h << 7) + ($h << 4) + ($h << 1) + $h) & 0xffffffff )) done # xor-fold to 16 bits print -nr -- $(( ($h >> 16) ^ ($h & 0xffff) )) } function color_hash { local bright impl flag h n s bright=false impl=_color_hash_fnv1a while getopts bi: flag; do case $flag in b) bright=true ;; i) if [[ $OPTARG != @(djb2|fnv1|fnv1a) ]]; then return 1 fi impl=_color_hash_$OPTARG ;; *) return 1 ;; esac done shift $(($OPTIND - 1)) h= s=$(print -nr -- "$1" | od -A n -t x1 | tr -d '[:space:]*') while :; do h=$($impl "$s" $h) # Avoid modulo bias. (( $h >= 4 )) && break done h=$(( $h % 12 )) if $bright; then # $h < 6 ? 8 + 1 + $h : 8 + 1 + $h - 6 n=$(( $h + ($h < 6 ? 9 : 3) )) else # $h < 6 ? 1 + $h : 8 + 1 + $h - 6 n=$(( $h + ($h < 6 ? 1 : 3) )) fi print -nr -- "$n" }