#!/usr/bin/env bash
# trit4_carrier.sh
# 4-trit balanced ternary encoding/decoding (81 possible values)
# with carrier wave overlay
set -euo pipefail
declare -A char_to_trits
declare -A trits_to_char
# Helper: Decimal to 4-trit Balanced Ternary string
decimal_to_trits() {
local n=$1
local trits=""
for ((i=0; i<4; i++)); do
local rem=$(( n % 3 ))
# FIX: Normalize negative remainders
if (( rem < 0 )); then
rem=$(( rem + 3 ))
fi
case $rem in
0) trits="=$trits"; n=$(( n / 3 )) ;;
1) trits="+$trits"; n=$(( (n - 1) / 3 )) ;;
2) trits="-$trits"; n=$(( (n + 1) / 3 )) ;;
esac
done
echo "$trits"
}
# Populate the 81-slot map
# 0 = Space
char_to_trits[' ']="===="
# Assign A-Z to 1 through 26
chars=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
for i in "${!chars[@]}"; do
val=$((i + 1))
trits=$(decimal_to_trits $val)
char_to_trits["${chars[$i]}"]="$trits"
done
# Assign a-z to -1 through -26
lchars=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
for i in "${!lchars[@]}"; do
val=$(( -(i + 1) ))
trits=$(decimal_to_trits $val)
char_to_trits["${lchars[$i]}"]="$trits"
done
# Assign 0-9 to 27 through 36
digits=(0 1 2 3 4 5 6 7 8 9)
for i in "${!digits[@]}"; do
val=$((i + 27))
trits=$(decimal_to_trits $val)
char_to_trits["${digits[$i]}"]="$trits"
done
# Punctuation and special characters (37-40 and remaining slots)
# Basic punctuation
char_to_trits['.']="++-+" # 37
char_to_trits[',']="++===" # 38
char_to_trits['?']="++=+" # 39
char_to_trits['!']="+++=" # 40
# Additional punctuation (negative range)
char_to_trits[';']="--=+" # -27
char_to_trits[':']="--=-" # -28
char_to_trits["'"]="--==" # -29
char_to_trits['"']="--=+" # -30
char_to_trits['-']="--+-" # -31
char_to_trits['_']="--+=" # -32
char_to_trits['(']="--++" # -33
char_to_trits[')']="-=--" # -34
char_to_trits['[']="--=-" # -35
char_to_trits[']']="-=-=" # -36
char_to_trits['{']="-==-" # -37
char_to_trits['}']="-=-+" # -38
char_to_trits['/']="--==" # -39
char_to_trits['\']="-+++" # -40
# Create Reverse Map
for char in "${!char_to_trits[@]}"; do
trits_to_char["${char_to_trits[$char]}"]="$char"
done
# XOR-like operation for balanced ternary
# Carrier: += -= += -= ...
# Message: any trit
# Result: modular addition in {-1, 0, 1}
overlay_with_carrier() {
local message="$1"
local carrier_pattern="+=-="
local result=""
local carrier_pos=0
for ((i=0; i<${#message}; i++)); do
local msg_trit="${message:i:1}"
local car_trit="${carrier_pattern:carrier_pos:1}"
# Convert trits to numeric values
case $msg_trit in
'+') msg_val=1 ;;
'=') msg_val=0 ;;
'-') msg_val=-1 ;;
esac
case $car_trit in
'+') car_val=1 ;;
'=') car_val=0 ;;
'-') car_val=-1 ;;
esac
# Add and wrap to balanced ternary range
sum=$((msg_val + car_val))
case $sum in
-2) result+="+"; ;; # Wrap around
-1) result+="-"; ;;
0) result+="="; ;;
1) result+="+"; ;;
2) result+="-"; ;; # Wrap around
esac
# Advance carrier position
carrier_pos=$(( (carrier_pos + 1) % 4 ))
done
echo "$result"
}
# Remove carrier wave (reverse operation)
remove_carrier() {
local encoded="$1"
local carrier_pattern="+=-="
local result=""
local carrier_pos=0
for ((i=0; i<${#encoded}; i++)); do
local enc_trit="${encoded:i:1}"
local car_trit="${carrier_pattern:carrier_pos:1}"
case $enc_trit in
'+') enc_val=1 ;;
'=') enc_val=0 ;;
'-') enc_val=-1 ;;
esac
case $car_trit in
'+') car_val=1 ;;
'=') car_val=0 ;;
'-') car_val=-1 ;;
esac
# Subtract carrier
diff=$((enc_val - car_val))
case $diff in
-2) result+="+"; ;;
-1) result+="-"; ;;
0) result+="="; ;;
1) result+="+"; ;;
2) result+="-"; ;;
esac
carrier_pos=$(( (carrier_pos + 1) % 4 ))
done
echo "$result"
}
encode() {
local text="$1"
local result=""
for ((i=0; i<${#text}; i++)); do
local c="${text:i:1}"
if [[ -n "${char_to_trits[$c]:-}" ]]; then
result+="${char_to_trits[$c]}"
else
echo "Warning: Unknown character '$c', skipping" >&2
fi
done
echo "$result"
}
decode() {
local trits="$1"
local result=""
for ((i=0; i<${#trits}; i+=4)); do
local block="${trits:i:4}"
if [[ -n "${trits_to_char[$block]:-}" ]]; then
result+="${trits_to_char[$block]}"
else
result+="?"
fi
done
echo "$result"
}
# Main script logic
if [[ $# -lt 2 ]]; then
echo "Usage: $0 [encode|decode] 'text' [--carrier]"
echo " --carrier: Apply carrier wave overlay for encoding"
exit 1
fi
use_carrier=false
if [[ $# -ge 3 && "$3" == "--carrier" ]]; then
use_carrier=true
fi
case "$1" in
encode)
encoded=$(encode "$2")
if $use_carrier; then
encoded=$(overlay_with_carrier "$encoded")
fi
echo "$encoded"
;;
decode)
trits="$2"
if $use_carrier; then
trits=$(remove_carrier "$trits")
fi
decode "$trits"
;;
*)
echo "Invalid command. Use 'encode' or 'decode'"
exit 1
;;
esac