Skip to content

Instantly share code, notes, and snippets.

@td-shi
Last active March 15, 2021 13:27
Show Gist options
  • Save td-shi/3be2baca7835cdae8be891e09196dacf to your computer and use it in GitHub Desktop.
Save td-shi/3be2baca7835cdae8be891e09196dacf to your computer and use it in GitHub Desktop.
Generate checkdigit by damm algorithm.
#!/bin/sh
# -*- coding:utf-8 posix -*-
# === Coding shell scripting Memo ==============================================
# ${<name>#<pattern>} :: matching delete with shortest by forword.
# ${<name>##<pattern>} :: matching delete with longest by forword.
# ${<name>%<pattern>} :: matching delete with shortest by backword.
# ${<name>%%<pattern>} :: mathing delete with longest by backword.
# ${<name>/<before>/<after>} :: replace only first matching.
# ${<name>//<before>/<after>} :: replace all matching.
# ${<name>:-<value>} :: if no yet set value, return value.
# ${<name>:=<value>} :: if no yet set value, return value and set.
# ". <shell script>" is to keep current shell and take over environment.
# === Initialize shell environment =============================================
#set -u # Just stop undefined values.
#set -e # Just stop error.
#set -x # Debug running command.
umask 0022
export LC_ALL=C
export LANG=C
PATH="$(command -p getconf PATH 2>/dev/null)${PATH+:}${PATH-}"
case $PATH in :*) PATH=${PATH#?};; esac
export PATH # or PATH="<add dir>${PATH+:}${PATH-}"
export UNIX_STD=2003 # to make HP-UX conform to POSIX
# === Define the functions for printing usage and error message ================
usage_and_exit(){
cat <<-"USAGE" 1>&2
# About
The damm.sh generate checkdigit by damm algorithm. The '-x' or '-X' option
change generate to hex from digit.
# Usage
## Command
damm.sh [option] [file]
The standard input shall be used, if no file operand is specified.
## Options
- -h |--help |--version
+ This help.
- -x
+ Set hex mode. And output lower-camel.
- -X
+ Set hex mode. And output upper-camel.
# Version
2021-03-12T21:12:10 0.01 [Search](https://gist.github.com/search?q=user%3Atd-shi+filename%3A.sh+damm)
# LICENSE
[CC0(Public domain)](https://creativecommons.org/publicdomain/zero/1.0/legalcode)
# Author
2021 TD
# Appendix
1. damm table for digit. (https://ja.wikipedia.org/wiki/Damm%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)
| - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 0 | 3 | 1 | 7 | 5 | 9 | 8 | 6 | 4 | 2 |
| 1 | 7 | 0 | 9 | 2 | 1 | 5 | 4 | 8 | 6 | 3 |
| 2 | 4 | 2 | 0 | 6 | 8 | 7 | 1 | 3 | 5 | 9 |
| 3 | 1 | 7 | 5 | 0 | 9 | 8 | 3 | 4 | 2 | 6 |
| 4 | 6 | 1 | 2 | 3 | 0 | 4 | 5 | 9 | 7 | 8 |
| 5 | 3 | 6 | 7 | 4 | 2 | 0 | 9 | 5 | 8 | 1 |
| 6 | 5 | 8 | 6 | 9 | 7 | 2 | 0 | 1 | 3 | 4 |
| 7 | 8 | 9 | 4 | 5 | 3 | 6 | 2 | 0 | 1 | 7 |
| 8 | 9 | 4 | 3 | 8 | 6 | 1 | 7 | 2 | 0 | 5 |
| 9 | 2 | 5 | 8 | 1 | 4 | 3 | 6 | 7 | 9 | 0 |
2. damm table for hex. (http://www.md-software.de/math/DAMM_Quasigruppen.txt)
| - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 00 | 02 | 04 | 06 | 08 | 10 | 12 | 14 | 03 | 01 | 07 | 05 | 11 | 09 | 15 | 13 |
| 1 | 02 | 00 | 06 | 04 | 10 | 08 | 14 | 12 | 01 | 03 | 05 | 07 | 09 | 11 | 13 | 15 |
| 2 | 04 | 06 | 00 | 02 | 12 | 14 | 08 | 10 | 07 | 05 | 03 | 01 | 15 | 13 | 11 | 09 |
| 3 | 06 | 04 | 02 | 00 | 14 | 12 | 10 | 08 | 05 | 07 | 01 | 03 | 13 | 15 | 09 | 11 |
| 4 | 08 | 10 | 12 | 14 | 00 | 02 | 04 | 06 | 11 | 09 | 15 | 13 | 03 | 01 | 07 | 05 |
| 5 | 10 | 08 | 14 | 12 | 02 | 00 | 06 | 04 | 09 | 11 | 13 | 15 | 01 | 03 | 05 | 07 |
| 6 | 12 | 14 | 08 | 10 | 04 | 06 | 00 | 02 | 15 | 13 | 11 | 09 | 07 | 05 | 03 | 01 |
| 7 | 14 | 12 | 10 | 08 | 06 | 04 | 02 | 00 | 13 | 15 | 09 | 11 | 05 | 07 | 01 | 03 |
| 8 | 03 | 01 | 07 | 05 | 11 | 09 | 15 | 13 | 00 | 02 | 04 | 06 | 08 | 10 | 12 | 14 |
| 9 | 01 | 03 | 05 | 07 | 09 | 11 | 13 | 15 | 02 | 00 | 06 | 04 | 10 | 08 | 14 | 12 |
| 10 | 07 | 05 | 03 | 01 | 15 | 13 | 11 | 09 | 04 | 06 | 00 | 02 | 12 | 14 | 08 | 10 |
| 11 | 05 | 07 | 01 | 03 | 13 | 15 | 09 | 11 | 06 | 04 | 02 | 00 | 14 | 12 | 10 | 08 |
| 12 | 11 | 09 | 15 | 13 | 03 | 01 | 07 | 05 | 08 | 10 | 12 | 14 | 00 | 02 | 04 | 06 |
| 13 | 09 | 11 | 13 | 15 | 01 | 03 | 05 | 07 | 10 | 08 | 14 | 12 | 02 | 00 | 06 | 04 |
| 14 | 15 | 13 | 11 | 09 | 07 | 05 | 03 | 01 | 12 | 14 | 08 | 10 | 04 | 06 | 00 | 02 |
| 15 | 13 | 15 | 09 | 11 | 05 | 07 | 01 | 03 | 14 | 12 | 10 | 08 | 06 | 04 | 02 | 00 |
USAGE
exit 1
}
error_exit() {
${2+:} false && echo "${0##*/}: $2" 1>&2
exit "$1"
}
# === Initialize parameters ====================================================
SED_LF=$(printf '\\\n_')
SED_LF=${SED_LF%_}
IN_FILE=''
CODEC='d'
# === Confirm that the required commands exist =================================
# === Print usage and exit if one of the help options is set ===================
case "$# ${1:-}" in
'1 -h'|'1 --help'|'1 --version') usage_and_exit;;
esac
# === Read options =============================================================
while :; do
case "${1:-}" in
-X)
CODEC='X'
shift
;;
-x)
CODEC='x'
shift
;;
--|-)
break
;;
--*|-*)
error_exit 1 'Invalid option.'
;;
*)
break
;;
esac
done
# === Require parameters check =================================================
# === Last parameter ===========================================================
case $# in
0) : ;;
1) IN_FILE=$1 ;;
*) error_exit 1 'Too many args.' ;;
esac
if [ "_$IN_FILE" = '_' ] ||
[ "_$IN_FILE" = '_-' ] ||
[ "_$IN_FILE" = '_/dev/stdin' ] ||
[ "_$IN_FILE" = '_/dev/fd/0' ] ||
[ "_$IN_FILE" = '_/proc/self/fd/0' ] ; then
IN_FILE=''
elif [ -f "$IN_FILE" ] ||
[ -c "$IN_FILE" ] ||
[ -p "$IN_FILE" ] ; then
[ -r "$IN_FILE" ] || error_exit 1 'Cannot open the file: '"$IN_FILE"
else
usage_and_exit
fi
case "$IN_FILE" in ''|-|/*|./*|../*) :;; *) IN_FILE="./$IN_FILE";; esac
# === Define funcitons =========================================================
# === Main routine =============================================================
# shellcheck disable=SC2002
cat ${IN_FILE:+"$IN_FILE"} |\
tr -Cd "0123456789abcdefABCDEF\n" |\
case "-$CODEC" in -x|-X) tr "abcdef" "ABCDEF";; *) tr -d "abcdefABCDEF";; esac |\
sed "s/./&${SED_LF}/g" |\
sed "/~$/d" |\
case "-$CODEC" in
-x|-X)
sed "s/A/10/" |\
sed "s/B/11/" |\
sed "s/C/12/" |\
sed "s/D/13/" |\
sed "s/E/14/" |\
sed "s/F/15/" |\
awk '
BEGIN {
VT = 0;
LF = sprintf("\n");
fmt[ 0][ 0] = 0; fmt[ 0][ 1] = 2; fmt[ 0][ 2] = 4; fmt[ 0][ 3] = 6;
fmt[ 0][ 4] = 8; fmt[ 0][ 5] = 10; fmt[ 0][ 6] = 12; fmt[ 0][ 7] = 14;
fmt[ 0][ 8] = 3; fmt[ 0][ 9] = 1; fmt[ 0][10] = 7; fmt[ 0][11] = 5;
fmt[ 0][12] = 11; fmt[ 0][13] = 9; fmt[ 0][14] = 15; fmt[ 0][15] = 13;
fmt[ 1][ 0] = 2; fmt[ 1][ 1] = 0; fmt[ 1][ 2] = 6; fmt[ 1][ 3] = 4;
fmt[ 1][ 4] = 10; fmt[ 1][ 5] = 8; fmt[ 1][ 6] = 14; fmt[ 1][ 7] = 12;
fmt[ 1][ 8] = 1; fmt[ 1][ 9] = 3; fmt[ 1][10] = 5; fmt[ 1][11] = 7;
fmt[ 1][12] = 9; fmt[ 1][13] = 11; fmt[ 1][14] = 13; fmt[ 1][15] = 15;
fmt[ 2][ 0] = 4; fmt[ 2][ 1] = 6; fmt[ 2][ 2] = 0; fmt[ 2][ 3] = 2;
fmt[ 2][ 4] = 12; fmt[ 2][ 5] = 14; fmt[ 2][ 6] = 8; fmt[ 2][ 7] = 10;
fmt[ 2][ 8] = 7; fmt[ 2][ 9] = 5; fmt[ 2][10] = 3; fmt[ 2][11] = 1;
fmt[ 2][12] = 15; fmt[ 2][13] = 13; fmt[ 2][14] = 11; fmt[ 2][15] = 9;
fmt[ 3][ 0] = 6; fmt[ 3][ 1] = 4; fmt[ 3][ 2] = 2; fmt[ 3][ 3] = 0;
fmt[ 3][ 4] = 14; fmt[ 3][ 5] = 12; fmt[ 3][ 6] = 10; fmt[ 3][ 7] = 8;
fmt[ 3][ 8] = 5; fmt[ 3][ 9] = 7; fmt[ 3][10] = 1; fmt[ 3][11] = 3;
fmt[ 3][12] = 13; fmt[ 3][13] = 15; fmt[ 3][14] = 9; fmt[ 3][15] = 11;
fmt[ 4][ 0] = 8; fmt[ 4][ 1] = 10; fmt[ 4][ 2] = 12; fmt[ 4][ 3] = 14;
fmt[ 4][ 4] = 0; fmt[ 4][ 5] = 2; fmt[ 4][ 6] = 4; fmt[ 4][ 7] = 6;
fmt[ 4][ 8] = 11; fmt[ 4][ 9] = 9; fmt[ 4][10] = 15; fmt[ 4][11] = 13;
fmt[ 4][12] = 3; fmt[ 4][13] = 1; fmt[ 4][14] = 7; fmt[ 4][15] = 5;
fmt[ 5][ 0] = 10; fmt[ 5][ 1] = 8; fmt[ 5][ 2] = 14; fmt[ 5][ 3] = 12;
fmt[ 5][ 4] = 2; fmt[ 5][ 5] = 0; fmt[ 5][ 6] = 6; fmt[ 5][ 7] = 4;
fmt[ 5][ 8] = 9; fmt[ 5][ 9] = 11; fmt[ 5][10] = 13; fmt[ 5][11] = 15;
fmt[ 5][12] = 1; fmt[ 5][13] = 3; fmt[ 5][14] = 5; fmt[ 5][15] = 7;
fmt[ 6][ 0] = 12; fmt[ 6][ 1] = 14; fmt[ 6][ 2] = 8; fmt[ 6][ 3] = 10;
fmt[ 6][ 4] = 4; fmt[ 6][ 5] = 6; fmt[ 6][ 6] = 0; fmt[ 6][ 7] = 2;
fmt[ 6][ 8] = 15; fmt[ 6][ 9] = 13; fmt[ 6][10] = 11; fmt[ 6][11] = 9;
fmt[ 6][12] = 7; fmt[ 6][13] = 5; fmt[ 6][14] = 3; fmt[ 6][15] = 1;
fmt[ 7][ 0] = 14; fmt[ 7][ 1] = 12; fmt[ 7][ 2] = 10; fmt[ 7][ 3] = 8;
fmt[ 7][ 4] = 6; fmt[ 7][ 5] = 4; fmt[ 7][ 6] = 2; fmt[ 7][ 7] = 0;
fmt[ 7][ 8] = 13; fmt[ 7][ 9] = 15; fmt[ 7][10] = 9; fmt[ 7][11] = 11;
fmt[ 7][12] = 5; fmt[ 7][13] = 7; fmt[ 7][14] = 1; fmt[ 7][15] = 3;
fmt[ 8][ 0] = 3; fmt[ 8][ 1] = 1; fmt[ 8][ 2] = 7; fmt[ 8][ 3] = 5;
fmt[ 8][ 4] = 11; fmt[ 8][ 5] = 9; fmt[ 8][ 6] = 15; fmt[ 8][ 7] = 13;
fmt[ 8][ 8] = 0; fmt[ 8][ 9] = 2; fmt[ 8][10] = 4; fmt[ 8][11] = 6;
fmt[ 8][12] = 8; fmt[ 8][13] = 10; fmt[ 8][14] = 12; fmt[ 8][15] = 14;
fmt[ 9][ 0] = 1; fmt[ 9][ 1] = 3; fmt[ 9][ 2] = 5; fmt[ 9][ 3] = 7;
fmt[ 9][ 4] = 9; fmt[ 9][ 5] = 11; fmt[ 9][ 6] = 13; fmt[ 9][ 7] = 15;
fmt[ 9][ 8] = 2; fmt[ 9][ 9] = 0; fmt[ 9][10] = 6; fmt[ 9][11] = 4;
fmt[ 9][12] = 10; fmt[ 9][13] = 8; fmt[ 9][14] = 14; fmt[ 9][15] = 12;
fmt[10][ 0] = 7; fmt[10][ 1] = 5; fmt[10][ 2] = 3; fmt[10][ 3] = 1;
fmt[10][ 4] = 15; fmt[10][ 5] = 13; fmt[10][ 6] = 11; fmt[10][ 7] = 9;
fmt[10][ 8] = 4; fmt[10][ 9] = 6; fmt[10][10] = 0; fmt[10][11] = 2;
fmt[10][12] = 12; fmt[10][13] = 14; fmt[10][14] = 8; fmt[10][15] = 10;
fmt[11][ 0] = 5; fmt[11][ 1] = 7; fmt[11][ 2] = 1; fmt[11][ 3] = 3;
fmt[11][ 4] = 13; fmt[11][ 5] = 15; fmt[11][ 6] = 9; fmt[11][ 7] = 11;
fmt[11][ 8] = 6; fmt[11][ 9] = 4; fmt[11][10] = 2; fmt[11][11] = 0;
fmt[11][12] = 14; fmt[11][13] = 12; fmt[11][14] = 10; fmt[11][15] = 8;
fmt[12][ 0] = 11; fmt[12][ 1] = 9; fmt[12][ 2] = 15; fmt[12][ 3] = 13;
fmt[12][ 4] = 3; fmt[12][ 5] = 1; fmt[12][ 6] = 7; fmt[12][ 7] = 5;
fmt[12][ 8] = 8; fmt[12][ 9] = 10; fmt[12][10] = 12; fmt[12][11] = 14;
fmt[12][12] = 0; fmt[12][13] = 2; fmt[12][14] = 4; fmt[12][15] = 6;
fmt[13][ 0] = 9; fmt[13][ 1] = 11; fmt[13][ 2] = 13; fmt[13][ 3] = 15;
fmt[13][ 4] = 1; fmt[13][ 5] = 3; fmt[13][ 6] = 5; fmt[13][ 7] = 7;
fmt[13][ 8] = 10; fmt[13][ 9] = 8; fmt[13][10] = 14; fmt[13][11] = 12;
fmt[13][12] = 2; fmt[13][13] = 0; fmt[13][14] = 6; fmt[13][15] = 4;
fmt[14][ 0] = 15; fmt[14][ 1] = 13; fmt[14][ 2] = 11; fmt[14][ 3] = 9;
fmt[14][ 4] = 7; fmt[14][ 5] = 5; fmt[14][ 6] = 3; fmt[14][ 7] = 1;
fmt[14][ 8] = 12; fmt[14][ 9] = 14; fmt[14][10] = 8; fmt[14][11] = 10;
fmt[14][12] = 4; fmt[14][13] = 6; fmt[14][14] = 0; fmt[14][15] = 2;
fmt[15][ 0] = 13; fmt[15][ 1] = 15; fmt[15][ 2] = 9; fmt[15][ 3] = 11;
fmt[15][ 4] = 5; fmt[15][ 5] = 7; fmt[15][ 6] = 1; fmt[15][ 7] = 3;
fmt[15][ 8] = 14; fmt[15][ 9] = 12; fmt[15][10] = 10; fmt[15][11] = 8;
fmt[15][12] = 6; fmt[15][13] = 4; fmt[15][14] = 2; fmt[15][15] = 0;
}
/[0-9]+/ { VT = fmt[VT][$0]; }
END { printf "%x\n", VT; }'
;;
*)
awk '
BEGIN {
VT = 0;
LF = sprintf("\n");
fmt[ 0][ 0] = 0; fmt[ 0][ 1] = 3; fmt[ 0][ 2] = 1; fmt[ 0][ 3] = 7;
fmt[ 0][ 4] = 5; fmt[ 0][ 5] = 9; fmt[ 0][ 6] = 8; fmt[ 0][ 7] = 6;
fmt[ 0][ 8] = 4; fmt[ 0][ 9] = 2;
fmt[ 1][ 0] = 7; fmt[ 1][ 1] = 0; fmt[ 1][ 2] = 9; fmt[ 1][ 3] = 2;
fmt[ 1][ 4] = 1; fmt[ 1][ 5] = 5; fmt[ 1][ 6] = 4; fmt[ 1][ 7] = 8;
fmt[ 1][ 8] = 6; fmt[ 1][ 9] = 3;
fmt[ 2][ 0] = 4; fmt[ 2][ 1] = 2; fmt[ 2][ 2] = 0; fmt[ 2][ 3] = 6;
fmt[ 2][ 4] = 8; fmt[ 2][ 5] = 7; fmt[ 2][ 6] = 1; fmt[ 2][ 7] = 3;
fmt[ 2][ 8] = 5; fmt[ 2][ 9] = 9;
fmt[ 3][ 0] = 1; fmt[ 3][ 1] = 7; fmt[ 3][ 2] = 5; fmt[ 3][ 3] = 0;
fmt[ 3][ 4] = 9; fmt[ 3][ 5] = 8; fmt[ 3][ 6] = 3; fmt[ 3][ 7] = 4;
fmt[ 3][ 8] = 2; fmt[ 3][ 9] = 6;
fmt[ 4][ 0] = 6; fmt[ 4][ 1] = 1; fmt[ 4][ 2] = 2; fmt[ 4][ 3] = 3;
fmt[ 4][ 4] = 0; fmt[ 4][ 5] = 4; fmt[ 4][ 6] = 5; fmt[ 4][ 7] = 9;
fmt[ 4][ 8] = 7; fmt[ 4][ 9] = 8;
fmt[ 5][ 0] = 3; fmt[ 5][ 1] = 6; fmt[ 5][ 2] = 7; fmt[ 5][ 3] = 4;
fmt[ 5][ 4] = 2; fmt[ 5][ 5] = 0; fmt[ 5][ 6] = 9; fmt[ 5][ 7] = 5;
fmt[ 5][ 8] = 8; fmt[ 5][ 9] = 1;
fmt[ 6][ 0] = 5; fmt[ 6][ 1] = 8; fmt[ 6][ 2] = 6; fmt[ 6][ 3] = 9;
fmt[ 6][ 4] = 7; fmt[ 6][ 5] = 2; fmt[ 6][ 6] = 0; fmt[ 6][ 7] = 1;
fmt[ 6][ 8] = 3; fmt[ 6][ 9] = 4;
fmt[ 7][ 0] = 8; fmt[ 7][ 1] = 9; fmt[ 7][ 2] = 4; fmt[ 7][ 3] = 5;
fmt[ 7][ 4] = 3; fmt[ 7][ 5] = 6; fmt[ 7][ 6] = 2; fmt[ 7][ 7] = 0;
fmt[ 7][ 8] = 1; fmt[ 7][ 9] = 7;
fmt[ 8][ 0] = 9; fmt[ 8][ 1] = 4; fmt[ 8][ 2] = 3; fmt[ 8][ 3] = 8;
fmt[ 8][ 4] = 6; fmt[ 8][ 5] = 1; fmt[ 8][ 6] = 7; fmt[ 8][ 7] = 2;
fmt[ 8][ 8] = 0; fmt[ 8][ 9] = 5;
fmt[ 9][ 0] = 2; fmt[ 9][ 1] = 5; fmt[ 9][ 2] = 8; fmt[ 9][ 3] = 1;
fmt[ 9][ 4] = 4; fmt[ 9][ 5] = 3; fmt[ 9][ 6] = 6; fmt[ 9][ 7] = 7;
fmt[ 9][ 8] = 9; fmt[ 9][ 9] = 0;
}
/[0-9]+/ { VT = fmt[VT][$0]; }
END { printf "%x\n", VT; }'
;;
esac |\
case "-${CODEC}" in -X) tr "abcdef" "ABCDEF";; *) cat -;; esac
# === End shell script =========================================================
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment