#!/usr/bin/env bash
set -Eeuo pipefail

count=false
while (($# > 0)); do
  case "$1" in
  -c | --count) count=true ;;
  --) shift && break ;;
  *) break ;;
  esac
  shift
done

parent=${1:?missing required parent argument}
child=${2:?missing required child argument}

declare -Ar char_map=(
  [a]=2
  [b]=3
  [c]=5
  [d]=7
  [e]=11
  [f]=13
  [g]=17
  [h]=19
  [i]=23
  [j]=29
  [k]=31
  [l]=37
  [m]=41
  [n]=43
  [o]=47
  [p]=53
  [q]=59
  [r]=61
  [s]=67
  [t]=71
  [u]=73
  [v]=79
  [w]=83
  [x]=89
  [y]=97
  [z]=101
  [A]=103
  [B]=107
  [C]=109
  [D]=113
  [E]=127
  [F]=131
  [G]=137
  [H]=139
  [I]=149
  [J]=151
  [K]=163
  [L]=167
  [M]=173
  [N]=179
  [O]=181
  [P]=191
  [Q]=193
  [R]=197
  [S]=199
  [T]=211
  [U]=223
  [V]=227
  [W]=229
  [X]=233
  [Y]=239
  [Z]=241
)

hash() {
  declare -i hash=1
  while read -rn1 c; do
    if [[ "$c" != '' ]]; then
      hash=$((hash * ${char_map[$c]}))
    fi
  done <<<"$1"
  echo $hash
}

child_hash=$(hash "$child")
matches=()
for ((start = 0; start < $((${#parent} - ${#child})); start++)); do
  substring=${parent:$start:${#child}}
  if [[ "$child_hash" == "$(hash "$substring")" ]]; then
    matches+=("$substring")
  fi
done

if [[ $count == true ]]; then
  echo "${#matches[@]}"
else
  printf '%s\n' "${matches[@]}"
fi
