#!/bin/bash # md5-crypt for GNU and Bash # By Vidar 'koala_man' Holen b64="./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" stringToNumber() { expression=0 for((i=0; i<${#1}; i++)) do expression=$(printf '(%s)*256+%d' "$expression" "'${1:$i:1}") done bc <<< "$expression" } # Turn some string into a \xd4\x1d hex string stringToHex() { for((i=0; i<${#1}; i++)) do printf '\\x%x' "'${1:i:1}" done } # Turn stdin into a \xd4\x1d style md5 hash md5hex() { sum=$(md5sum) read sum rest <<< "$sum" # remove trailing dash hex=$(sed 's/../\\x&/g' <<< "$sum") echo "$hex" } # Turn an integer into a crypt base64 string with n characters intToBase64() { number=$1 n=$2 for((j=0; j>=1)) do if (( i & 1 )) then printf '\x00' else printf "$password" | head -c 1 fi done } | md5hex ) for((i=0; i<1000; i++)) do intermediate=$({ (( i & 1 )) && printf "$password" || printf "$intermediate" (( i % 3 )) && printf "$salt" (( i % 7 )) && printf "$password" (( i & 1 )) && printf "$intermediate" || printf "$password" } | md5hex) done # Rearrange the bytes and crypt-base64 encode them encoded=$(base64EncodeBytes 22 "$intermediate" 11 4 10 5 3 9 15 2 8 14 1 7 13 0 6 12) printf "%s$salt\$%s\n" "$magic" "$encoded" } if [[ $# < 1 ]] then echo "Usage: $0 password [salt]" >&2 exit 1 fi password=$(stringToHex "$1") salt=$(stringToHex "$2") [[ -z $salt ]] && salt=$(tr -cd 'a-zA-Z0-9' < /dev/urandom | head -c 8) doHash "$password" "$salt" '$1$'