2023-02-11 18:23:07 +01:00
|
|
|
function _color_hash_djb2
|
|
|
|
{
|
|
|
|
local c h s
|
|
|
|
s=$1
|
|
|
|
h=${2:-5381}
|
|
|
|
while (( ${#s} > 0 )); do
|
|
|
|
c=0x${s%${s#??}}
|
|
|
|
s=${s#??}
|
2023-10-24 21:51:20 +02:00
|
|
|
h=$(( ((($h << 5) + $h) ^ $c) & 0xffff ))
|
2023-02-11 18:23:07 +01:00
|
|
|
done
|
2023-10-24 21:51:20 +02:00
|
|
|
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) ))
|
2023-02-11 18:23:07 +01:00
|
|
|
}
|
|
|
|
|
2023-02-11 19:42:20 +01:00
|
|
|
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
|
2023-10-24 21:51:20 +02:00
|
|
|
print -nr -- $(( ($h >> 16) ^ ($h & 0xffff) ))
|
2023-02-11 19:42:20 +01:00
|
|
|
}
|
|
|
|
|
2024-07-13 15:56:18 +02:00
|
|
|
function _color_hash_sha
|
|
|
|
{
|
|
|
|
local c h s p
|
|
|
|
p=$1
|
|
|
|
shift
|
|
|
|
s=$(printf "%08x%s" "${2:-0}" "$1")
|
|
|
|
h=$("$p" -qs "$s")
|
|
|
|
c=$((0x${h#${h%?}}))
|
|
|
|
while (( $c > 0 )); do
|
|
|
|
h=${h#??}
|
|
|
|
c=$(($c - 1))
|
|
|
|
done
|
|
|
|
h=$((0x${h%${h#????}}))
|
|
|
|
print -nr -- $h
|
|
|
|
}
|
|
|
|
|
|
|
|
function _color_hash_sha1
|
|
|
|
{
|
|
|
|
_color_hash_sha sha1 "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
function _color_hash_sha256
|
|
|
|
{
|
|
|
|
_color_hash_sha sha256 "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
function _color_hash_sha512
|
|
|
|
{
|
|
|
|
_color_hash_sha sha512 "$@"
|
|
|
|
}
|
|
|
|
|
2023-02-11 18:23:07 +01:00
|
|
|
function color_hash
|
|
|
|
{
|
2023-02-11 19:42:20 +01:00
|
|
|
local bright impl flag h n s
|
2023-02-11 18:23:07 +01:00
|
|
|
|
|
|
|
bright=false
|
2023-02-11 19:42:20 +01:00
|
|
|
impl=_color_hash_fnv1a
|
|
|
|
while getopts bi: flag; do
|
2023-02-11 18:23:07 +01:00
|
|
|
case $flag in
|
|
|
|
b) bright=true ;;
|
2024-07-13 15:56:18 +02:00
|
|
|
i) if [[ $OPTARG != @(djb2|fnv1|fnv1a|sha1|sha256|sha512) ]]; then
|
2023-02-11 19:42:20 +01:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
impl=_color_hash_$OPTARG
|
|
|
|
;;
|
2023-02-11 18:23:07 +01:00
|
|
|
*) return 1 ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
shift $(($OPTIND - 1))
|
|
|
|
|
|
|
|
h=
|
2023-10-24 21:51:20 +02:00
|
|
|
s=$(print -nr -- "$1" | od -A n -t x1 | tr -d '[:space:]*')
|
2023-02-11 18:23:07 +01:00
|
|
|
while :; do
|
2023-02-11 19:42:20 +01:00
|
|
|
h=$($impl "$s" $h)
|
2023-02-11 18:23:07 +01:00
|
|
|
# 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
|
|
|
|
|
2023-10-24 21:51:20 +02:00
|
|
|
print -nr -- "$n"
|
2023-02-11 18:23:07 +01:00
|
|
|
}
|