#!/usr/bin/ksh93 ################################################################ function usagemsg_mkewuid { print -- " Program: mkewuid Generate an Enterprise Wide Unique (EWU) identifier value for any given input string of characters. For example, this script can be used to generate an Enterprise Wide Unique UID number for any given user name. The output value may be calculated in a user selectable format and number of digits. Usage: ${1##*/} [-?vV] [-hdob] [-mM] [-c] [-p #] [-ul] [string...] Where: -h = Hexadecimal (Base 16) output value (default) -d = Base 10 output value -o = Octal (Base 8) output value -b = Binary (Base 2) output value -p # = Number of characters in output value (default: 4) -c = Display column headers in output (default: no headers) -m = Minimize output -M = Maximize output (default) -u = Uppercase Enterprise Wide Unique output values -l = Lowercase Enterprise Wide Unique output values (default) -v = Verbose mode - displays mkewuid function info -V = Very Verbose Mode - debug output displayed -? = Help - display this message string = any alphanumeric string such as user names, group names, host names, node names, etc. (default: local node name ) Example Usage: mkewuid -c -h -p 6 teststring1 Example Output: # string : base : cksum : denom: modulo : ewuid teststring1:16:542276492:16777216:5405580:527b8c Author: Dana French (dfrench@mtxia.com) Copyright 2008 By Dana French, All Rights Reserved \"AutoContent\" enabled " } ################################################################ #### #### Description: #### #### Generate an enterprise wide unique identifier value for #### any given input string of characters. For example, this #### script can be used to generate an Enterprise Wide Unique #### UID number for any given user name. The output value #### may be calculated in a user selectable format and number #### of digits. #### #### The reason for wanting to use this script is to be able #### to consistently generate the same Enterprise Wide Unique #### identifier value for any given string on any system. #### This eliminates the need for keeping these values in #### spreadsheets and databases. For example, whenever you #### need to know the the enterprise wide unique value (UID #### number) for a user name, instead of having to look it up #### on a spread sheet, you can generate it using this #### script. #### #### Assumptions: #### #### Strings provided on the command line to be used to #### calculate Enterprise Wide Unique identifier values #### should be alphanumeric only. The required unix binary #### utilities are assumed to be available in a directory #### referenced by the PATH environment variable. #### #### The "shebang" line (#!/usr/bin/ksh93) of this script #### identifies the KornShell 93 location as "/usr/bin/ksh93. #### If your KornShell 93 binary is not at this location or #### is not named "ksh93", change this script to match your #### configuration. #### #### Dependencies: #### #### This script utilizes Korn Shell 93 specific features and #### requires the following external Unix binary utilities: #### #### uname #### cksum #### awk #### bc #### tr #### #### All of the above unix binary utilities are normally located #### in the "/usr/bin" directory, and is usually included #### in the default PATH value. #### #### Products: #### #### This script generates a value that can be utilized as an #### Enterprise Wide Unique identifier. For example, this #### script can be utilized to generate Enterprise Wide #### Unique UID numbers for any user name. #### #### If the header line is selected by the user to be #### displayed in the output, it will identify each field in #### the output. Those fields are: #### #### string: The character string read from the command line, #### as provided by the user. #### base: The counting base for the output, i.e. #### base 16 - hexadecimal (0-f) #### base 10 - normal counting digits 0-9 #### base 8 - octal (0-7) #### base 2 - binary (0-1) #### cksum: A CRC cksum is calculated for each string provided #### by the user on the command line. #### denom: This is calcuated from the counting base and the #### number of digits desired in the output value. This #### value is also the number of unique possibilities #### for the output values using the counting base and #### number of digits in the output value. #### modulo: The remainder from dividing the cksum value by the #### denom value. This is the base 10 unique value for #### the string provided by the user on the command line. #### ewuid: The Enterprise Wide Unique value translated into the #### desired output counting base and number of output #### characters. #### #### All EWU output values are converted to lower case value #### by default. The command line option "-u" can be used to #### convert it to upper case. #### #### Configured Usage: #### #### This script may be used from the command line or included #### in a script library and called as a function. #### #### Details: #### ################################################################ function mkewuid { typeset PRGNAME="mkewuid - Make an Enterprise Wide Unique Identifier" typeset COPYRIGHT="Copyright 2008 by Dana French, All Rights Reserved" typeset VERSION="1.0" typeset TRUE="1" typeset FALSE="0" typeset VERBOSE="${FALSE}" typeset VERYVERB="${FALSE}" typeset HEX="${FALSE}" typeset OCT="${FALSE}" typeset DIG="${FALSE}" typeset BIN="${FALSE}" typeset MIN="${FALSE}" typeset MAX="${TRUE}" typeset HDR="${FALSE}" typeset LC="${TRUE}" typeset UC="${FALSE}" typeset PLC="4" typeset MOD typeset ID typeset CKSUM typeset IDX typeset BASE typeset EXP typeset VAL IFS=$' \t\n' while getopts ":vVhdobp#mMclu" OPTION do case "${OPTION}" in 'v') VERBOSE="${TRUE}";; 'V') VERYVERB="${TRUE}";; 'h') HEX="${TRUE}";; 'd') DIG="${TRUE}";; 'o') OCT="${TRUE}";; 'b') BIN="${TRUE}";; 'm') MIN="${TRUE}" MAX="${FALSE}";; 'M') MAX="${TRUE}" MIN="${FALSE}";; 'p') PLC="${OPTARG}";; 'c') HDR="${TRUE}";; 'l') LC="${TRUE}" UC="${FALSE}";; 'u') UC="${TRUE}" LC="${FALSE}";; '?') usagemsg_mkewuid "${0}" && return 1 ;; ':') usagemsg_mkewuid "${0}" && return 1 ;; '#') usagemsg_mkewuid "${0}" && return 1 ;; esac done shift $(( ${OPTIND} - 1 )) (( HEX == FALSE )) && (( DIG == FALSE )) && (( OCT == FALSE )) && (( BIN == FALSE )) && HEX="${TRUE}" # DIG="${TRUE}" # OCT="${TRUE}" # BIN="${TRUE}" ################################################################ trap "usagemsg_mkewuid ${0}" EXIT if (( PLC < 1 )) then (( VERBOSE == TRUE )) && print -- "# Error: Number of output characters must be greater than 0" return 2 fi if (( PLC > 16 )) then (( VERBOSE == TRUE )) && print -- "# Error: Number of output characters should be less than or equal to 16" return 3 fi if (( MIN == FALSE )) && (( MAX == FALSE )) then (( VERBOSE == TRUE )) && print -- "# Error: MIN and MAX are both false" return 4 fi if (( MIN == TRUE )) && (( MAX == TRUE )) then (( VERBOSE == TRUE )) && print -- "# Error: MIN and MAX are both true" return 5 fi if (( LC == TRUE )) && (( UC == TRUE )) then (( VERBOSE == TRUE )) && print -- "# Error: Lowercase and Uppercase are both true" return 6 fi if (( LC == FALSE )) && (( UC == FALSE )) then (( VERBOSE == TRUE )) && print -- "# Error: Lowercase and Uppercase are both false" return 7 fi trap "-" EXIT ################################################################ typeset -A DEN (( HEX == TRUE )) && DEN["16^${PLC}"]=16 (( DIG == TRUE )) && DEN["10^${PLC}"]=10 (( OCT == TRUE )) && DEN["8^${PLC}"]=8 (( BIN == TRUE )) && DEN["2^${PLC}"]=2 (( VERYVERB == TRUE )) && set -x (( VERBOSE == TRUE )) && print -u 2 -- "# Program Name...: ${PRGNAME}" (( VERBOSE == TRUE )) && print -u 2 -- "# Copyright......: ${COPYRIGHT}" (( VERBOSE == TRUE )) && print -u 2 -- "# Version........: ${VERSION}" (( VERBOSE == TRUE )) && print -u 2 -- "# TRUE...........: ${TRUE}" (( VERBOSE == TRUE )) && print -u 2 -- "# FALSE..........: ${FALSE}" (( VERBOSE == TRUE )) && print -u 2 -- "# Display Headers: ${HDR}" (( VERBOSE == TRUE )) && print -u 2 -- "# Minimize output: ${MIN}" (( VERBOSE == TRUE )) && print -u 2 -- "# Maximize output: ${MAX}" (( VERBOSE == TRUE )) && print -u 2 -- "# Uppercase......: ${UC}" (( VERBOSE == TRUE )) && print -u 2 -- "# Lowercase......: ${LC}" (( VERBOSE == TRUE )) && print -u 2 -- "# Base 16 output.: ${HEX}" (( VERBOSE == TRUE )) && print -u 2 -- "# Base 10 output.: ${DIG}" (( VERBOSE == TRUE )) && print -u 2 -- "# Base 8 output.: ${OCT}" (( VERBOSE == TRUE )) && print -u 2 -- "# Base 2 output.: ${BIN}" (( VERBOSE == TRUE )) && print -u 2 -- "# Output Chars...: ${PLC}" for IDX in "${!DEN[@]}" do (( VERBOSE == TRUE )) && print -u 2 -- "# Counting base..: ${DEN[${IDX}]}" (( VERBOSE == TRUE )) && print -u 2 -- "# Denominator....: ${IDX} ( $(( ${IDX//^/**} )) )" done ################################################################ if (( ${#} == 0 )) then print -u 2 "#### No strings were specified on the command line, using the local node name" set -- $( uname -n 2>&1 | awk -F . '{ print $1 }' ) fi (( MAX == TRUE )) && (( HDR == TRUE )) && print -- "# string : base : cksum : denom: modulo : ewuid" (( MIN == TRUE )) && (( HDR == TRUE )) && print -- "# ewuid" #### #### Loop through each "string" value provided by the user on #### the command line and calculate an EWU identifier value #### for each. #### for VAL in "${@}" do #### Calculate the CRC cksum value for the user provided string value. CKSUM=$( print -- "${VAL}" | cksum | awk '{ print $1 }' ) (( VERBOSE == TRUE )) && print -u 2 -- "# String Value...: ${VAL}" (( VERBOSE == TRUE )) && print -u 2 -- "# cksum Value....: ${CKSUM}" #### #### Loop through each counting base definition as selected #### by the user on the command line, and use this counting #### base to generate an EWU identifier value for each. In #### the context of this script, there should only be a #### single value, however a for loop is used to extract that #### value from the associative array where it is stored. #### for IDX in "${!DEN[@]}" do unset ID #### Extract the counting base from the associative array value. BASE="${DEN[${IDX}]}" (( VERBOSE == TRUE )) && print -u 2 -- "# Counting Base..: ${BASE}" #### Extract the exponent from the counting base. EXP="${IDX##*^}" (( VERBOSE == TRUE )) && print -u 2 -- "# Exponent.......: ${EXP}" (( VERBOSE == TRUE )) && print -u 2 -- "# Denominator....: ${IDX} ( $(( ${IDX//^/**} )) )" #### Calculate the base 10 modulo (remainder) from dividing #### the CRC cksum value by the ( counting base exponentially #### raised to the number of output digits ). MOD=$( print -- "${CKSUM} % ${IDX}" | bc ) (( VERBOSE == TRUE )) && print -u 2 -- "# Modulo.........: ${MOD} (cksum%denom)" #### Convert the modulo to the user selected counting base #### and upper or lower case, as selected by the user. (( LC == TRUE )) && typeset -l ID=$( print -- "obase=${BASE}; ${MOD}" | bc ) (( UC == TRUE )) && typeset -u ID=$( print -- "obase=${BASE}; ${MOD}" | bc ) #### Zero fill the output value up to 16 digits, then select #### the correct number of output characters using a right #### justified typeset. typeset -R${EXP} ID="0000000000000000${ID}" #### Output the EWU identifier value according to desired #### structure as selected by the user. (( MAX == TRUE )) && print -- "${VAL}:${BASE}:${CKSUM}:$(( ${IDX//^/**} )):${MOD}:${ID}" (( MIN == TRUE )) && print -- "${ID}" done done return 0 } ################################################################ mkewuid "${@}"