Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #
- # Calculates the CRC-16 checksum of a string
- # like cksum does for CRC32
- #
- # Copyright (C) 2011 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
- # License: GPLv3 or later, at your choice. See <http://www.gnu.org/licenses/gpl>
- #
- # References:
- # 0x10 blog: <http://zeroxten.blogspot.com/search/label/crc16>
- # Wine's winemenubuilder: <http://source.winehq.org/git/wine.git>
- # The wise, friendly and helpful #bash gurus: <irc://irc.freenet.org/#bash>
- #
- # NOTE: Newlines are properly handled, but last newline is stripped off
- # NOTE: NUL chars are stripped off before computing
- # TODO: Test how non-ASCI chars are handled
- # FIXME: Decent usage explaining options and behaviour
- self="${0##*/}"
- error() {
- local msg="$1"
- printf "%s: %s\nTry '%s --help' for more information\n" \
- "$self" "$msg" "$self" >&2
- exit 1
- }
- usage() {
- printf "Print CRC-16 checksum (and optionally the byte count) of STRING\n\n"
- printf "Usage: %s [--hex|--dec|--format FORMAT] [--count] [STRING]\n\n" "$self"
- printf "Default format is decimal. If no string or -, reads from stdin\n"
- printf "NULs and last newline are ignored. Use for texts, not binary data.\n"
- exit
- }
- crc16()
- (
- export LC_ALL=C
- local string="$1"
- local format="${2:-"%d"}"
- local crc=0
- local i j xor_poly
- for ((i=0; i<${#string}; i++)); do
- c=$(printf "%d" "'${string:i:1}")
- for ((j=0; j<8; c>>=1, j++)); do
- (( xor_poly = (c ^ crc) & 1 ))
- (( crc >>= 1 ))
- (( xor_poly )) && (( crc ^= 0xA001 ))
- done
- done
- printf "$format" "$crc"
- )
- while [[ $# -gt 0 ]]; do
- arg="$1"; shift
- case "$arg" in
- -h|--help ) usage ;;
- -x|--hex ) format="%04X" ;;
- -d|--dec ) format="%d" ;;
- -f|--format) format="$1"; shift ;;
- -c|--count ) count=1 ;;
- -- ) string="$1" ; break ;;
- - ) string=$( cat ) ; done=1 ; break ;;
- -* ) error "unrecognized option '$arg'" ;;
- * ) string="$arg" ; done=1 ; break ;;
- esac
- done
- [[ "$done" || "$string" ]] || string=$( cat )
- # Expected command-line behaviour table:
- # <none> => str = stdin
- # - => str = stdin
- # something => str = something
- # -- <none> => str = stdin
- # -- someth => str = something
- [[ "$string" ]] || error "missing string"
- crc16 "$string" "$format"
- [[ "$count" ]] && printf " %d" "${#string}"
- printf "\n"
- #Original function from winemenubuilder.c (for reference)
- #static unsigned short crc16(const char* string)
- #{
- # unsigned short crc = 0;
- # int i, j, xor_poly;
- #
- # for (i = 0; string[i] != 0; i++)
- # {
- # char c = string[i];
- # for (j = 0; j < 8; c >>= 1, j++)
- # {
- # xor_poly = (c ^ crc) & 1;
- # crc >>= 1;
- # if (xor_poly)
- # crc ^= 0xa001;
- # }
- # }
- # return crc;
- #}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement