Skip to content

Instantly share code, notes, and snippets.

@akostadinov
Created June 12, 2026 15:07
Show Gist options
  • Select an option

  • Save akostadinov/5fa03bc7c2308d94a34bcc5d61fc75d3 to your computer and use it in GitHub Desktop.

Select an option

Save akostadinov/5fa03bc7c2308d94a34bcc5d61fc75d3 to your computer and use it in GitHub Desktop.
A script to dollar-sign encode any string.
#!/usr/bin/env ruby
# frozen_string_literal: true
# LICENSE: AGPL3, commercial licenses available from only $1 per 100 encoded characters.
# Encodes bytes into sequences of three dollar sign Unicode characters:
# U+0024 ($), U+FE69 (﹩), U+FF04 ($)
class DollarEncoder
# The three dollar sign characters used for encoding
DOLLAR_SIGNS = [
"\u0024", # $ - Regular dollar sign (represents 0)
"\uFE69", # ﹩ - Small dollar sign (represents 1)
"\uFF04" # $ - Fullwidth dollar sign (represents 2)
].freeze
# Encodes a string or bytes into dollar sign sequences
# @param input [String] The input string to encode
# @return [String] The encoded string using dollar sign characters
def self.encode(input)
input.bytes.map { |byte| encode_byte(byte) }.join
end
# Encodes a single byte into a sequence of dollar signs
# Uses base-3 representation with 6 digits (3^6 = 729 > 255)
# @param byte [Integer] A byte value (0-255)
# @return [String] A sequence of 6 dollar sign characters
def self.encode_byte(byte)
raise ArgumentError, "Byte must be between 0 and 255" unless byte.between?(0, 255)
# Convert to base-3 with 6 digits (padded with zeros)
base3_digits = []
value = byte
6.times do
base3_digits.unshift(value % 3)
value /= 3
end
# Map each base-3 digit to a dollar sign character
base3_digits.map { |digit| DOLLAR_SIGNS[digit] }.join
end
# Decodes a dollar sign sequence back to the original string
# @param encoded [String] The encoded string
# @return [String] The decoded original string
def self.decode(encoded)
# Split into groups of 6 characters
chars = encoded.chars
raise ArgumentError, "Encoded string length must be a multiple of 6" unless chars.length % 6 == 0
bytes = []
chars.each_slice(6) do |group|
bytes << decode_byte(group.join)
end
bytes.pack('C*').force_encoding('UTF-8')
end
# Decodes a 6-character dollar sign sequence back to a byte
# @param sequence [String] A 6-character sequence
# @return [Integer] The decoded byte value
def self.decode_byte(sequence)
raise ArgumentError, "Sequence must be 6 characters" unless sequence.length == 6
value = 0
sequence.each_char do |char|
digit = DOLLAR_SIGNS.index(char)
raise ArgumentError, "Invalid character in sequence: #{char}" if digit.nil?
value = value * 3 + digit
end
value
end
end
# Command-line interface
if __FILE__ == $PROGRAM_NAME
if ARGV.empty?
puts "Usage: #{File.basename($PROGRAM_NAME)} <text> [<text2> ...]"
puts "Encodes all arguments into dollar sign sequences."
puts ""
puts "Example:"
puts " #{File.basename($PROGRAM_NAME)} 'Hello World'"
puts ""
puts "To decode, use the --decode flag:"
puts " #{File.basename($PROGRAM_NAME)} --decode '<encoded_text>'"
exit 1
end
if ARGV[0] == '--decode'
# Decode mode
ARGV.shift
ARGV.each do |arg|
begin
decoded = DollarEncoder.decode(arg)
puts decoded
rescue ArgumentError => e
warn "Error decoding '#{arg}': #{e.message}"
end
end
else
# Encode mode (default)
ARGV.each do |arg|
encoded = DollarEncoder.encode(arg)
puts encoded
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment