Basic Auth Generator — Ruby source
Build HTTP Basic Access Authentication headers from a username and password, or decode an existing Authorization header back to its credentials. UTF-8 safe and fully client-side, with a shareable link.
This is the Ruby implementation — the same logic the interactive tool runs, in a shareable, citable form.
# basic-auth-generator — HTTP Basic-Auth header encode/decode.
#
# Language: Ruby (3.2+, standard library only)
# Source: CosmoDev polyglot showcase port of the Basic Auth Generator tool,
# ported from src/lib/basic-auth.ts (the canonical TypeScript
# implementation) and kept in lock-step with cli/basic-auth-generator.
# License: display source — part of CosmoDev's polyglot tool pages.
#
# Design goals:
# - Pure + deterministic; never raises (parse_header returns nil on
# malformed input).
# - Functionally equivalent to the TS reference + Go twin: same inputs ->
# same outputs, same reject behavior on malformed headers.
# - Self-contained: stdlib only (the base64 default gem, which ships with
# Ruby).
#
# Ruby is a dependency-rich polyglot here, like the Python port: the standard
# library ships an RFC 4648 codec. Base64.strict_encode64/strict_decode64 use
# the real standard path — strict_decode64 rejects invalid characters exactly
# like Go's base64.StdEncoding.DecodeString. Two quirks are compensated for
# below: the strict decoder does not skip whitespace, and its result is tagged
# ASCII-8BIT, so the bytes are re-tagged UTF-8 and validated before use.
require 'base64'
module BasicAuth
# A parsed username/password pair. Mirrors the Go twin's Credentials struct
# and the TS BasicAuthCredentials interface.
Credentials = Struct.new(:user, :pass)
module_function
# Build an HTTP Basic-Auth header value: "Basic " + base64(user:pass).
# Mirrors BuildHeader in the Go twin and buildBasicAuth in the TS source.
# strict_encode64 packs the string's bytes, so multibyte UTF-8 credentials
# (e.g. "café:päss") encode correctly.
def build_header(user, pass)
"Basic #{Base64.strict_encode64("#{user}:#{pass}")}"
end
# Parse a "Basic <token>" header back into credentials, or nil if the header
# is malformed or the credentials have no colon separator. Logic mirrors
# ParseHeader in the Go twin exactly: trim the header, require a
# case-insensitive "basic " prefix, trim the remaining token, base64-decode
# it (rejecting invalid characters), then split on the FIRST colon so a
# password containing colons round-trips.
def parse_header(header)
h = header.strip
prefix = 'basic '
return nil if h.length < prefix.length || h[0, prefix.length].downcase != prefix
token = h[prefix.length..].strip
# strict_decode64 does not skip whitespace; strip it and enforce the
# multiple-of-4 length ourselves — exactly like Go's StdEncoding.
cleaned = token.gsub(/\s+/, '')
return nil if cleaned.length % 4 != 0
decoded =
begin
Base64.strict_decode64(cleaned)
rescue ArgumentError
return nil
end
decoded = decoded.force_encoding(Encoding::UTF_8)
return nil unless decoded.valid_encoding?
user, pass = decoded.split(':', 2)
return nil if pass.nil? # no colon separator
Credentials.new(user, pass)
end
end
# ---------- showcase-only demo (canonical suite lives in src/lib) ----------
if __FILE__ == $PROGRAM_NAME
h = BasicAuth.build_header('user', 'pass')
raise "known vector mismatch: #{h}" unless h == 'Basic dXNlcjpwYXNz'
puts h
[['alice', 's3cr3t'], ['', 'x'], ['x', ''], ['u', 'a:b:c']].each do |user, pass|
creds = BasicAuth.parse_header(BasicAuth.build_header(user, pass))
raise "round trip should parse for (#{user}, #{pass})" if creds.nil?
raise "user mismatch for (#{user}, #{pass})" unless creds.user == user
# colon-bearing password stays intact: split happens on the first colon only
raise "password mismatch for (#{user}, #{pass})" unless creds.pass == pass
end
['Bearer xyz', '', 'Basic !!!not-base64!!!', 'Basic bm9jb2xvbg=='].each do |bad|
raise "#{bad} should be rejected" unless BasicAuth.parse_header(bad).nil?
end
puts 'all basic-auth-generator demo checks passed'
end
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →