David Bushong
Résumé
Software Tidbits
Links
Contact Me

Software Tidbits

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use open ':locale';
use Getopt::Std;
use File::Basename;

my %chars = (
  'a'    => 'ªàáâãäåāăąǎǟǡả',
  'ae'   => 'æǣ',
  'b'    => 'ЬбЪьъѢѣḇﻁḃ',
  'bl'   => 'Ы',
  'c'    => '¢çćĉċčςҁ',
  'd'    => 'ðďđδ∂ḋḏḑ',
  'e'    => 'ēèéêëĕėęěẻẽ',
  'f'    => 'ḟϝ',
  'ff'   => 'ff',
  'fi'   => 'fi',
  'fl'   => 'fl',
  'g'    => 'ĝğġģǥǧǵḡﻕǥ',
  'h'    => 'ĥħẖḣḧḩЋ',
  'i'    => 'ìíîïĩīĭįỉϊǐ¡',
  'ij'   => 'ij',
  'j'    => 'ĵǰﺫﺯ',
  'k'    => 'ĸḱḵǩ',
  'l'    => 'ĺļľŀłḻ',
  'm'    => 'ḿṁ',
  'n'    => 'ñńņňʼnŊŋη∩ṅṉמתή',
  'o'    => 'ōòóôõöø∅ỏѳσơǒŏő',
  'oe'   => 'œ',
  'p'    => 'ṕṗρ',
  'q'    => '¶۹',
  'r'    => 'ṙṟѓŗř',
  's'    => 'ṡﻯﻱﺉϟśŝşš',
  'st'   => 'st',
  't'    => '†ẗṫṯךţťŧ',
  'u'    => 'ǔưųµùúûü∪ủטџũūŭůű',
  'v'    => 'ṽעѵνϋύΰ',
  'w'    => 'ŵẘẇẅẁẃשωώ',
  'x'    => '×ẍẋχ',
  'y'    => 'ýÿỳỷỹẙẏўγŷ',
  'z'    => 'ƶẑẕźżž',
  'A'    => 'ǠÀÁÂÃÄǞÅĄÅẢ۸ΛΆǍ',
  'AE'   => 'ÆǢ',
  'B'    => 'ßḂḆ',
  'C'    => 'ÇĆĈĊČ℃ҀϚ',
  'D'    => 'ÐĎḊḎḐ',
  'E'    => 'ÈÉÊËĒ∑Σ∈€ẼﻉﻍξЄΈ',
  'F'    => '℉Ḟ',
  'G'    => 'ĜĞĠĢḠǤǴ',
  'H'    => 'ĤĦḢḦḨΉ',
  'I'    => 'ÌÍÎÏⅠỈΊǏ',
  'II'   => 'Ⅱ',
  'III'  => 'Ⅲ',
  'IV'   => 'Ⅳ',
  'IX'   => 'Ⅸ',
  'J'    => 'ﻙﻝ',
  'K'    => 'ĶKḰḴǨ',
  'L'    => '£₤ĹĻĽĿŁ∟Ḻ',
  'M'    => 'ḾṀ',
  'N'    => 'ÑŃŅŇṄṈИЙ',
  'Ni'   => '№',
  'O'    => 'ŌΌÒÓÔÕÖØỎѲϴΘƠǑŐ',
  'P'    => 'Ṗ',
  'Q'    => 'ϘǬǪ',
  'R'    => 'ṞṘЯƦŔŖŘ',
  'S'    => '§∮∫ṠŚŜŞŠ',
  'SS'   => '∬',
  'T'    => 'ṪṮŢŤŦ',
  'U'    => 'ƯŲÙÚÛÜỦǓŨŪŬŮŰ',
  'V'    => '√ⅤṼ۷Ѵ',
  'VI'   => 'Ⅵ',
  'VII'  => 'Ⅶ',
  'VIII' => 'Ⅷ',
  'W'    => '₩ẆẄẀẂШЩŴ',
  'X'    => 'ⅩẌẊ',
  'XI'   => 'Ⅺ',
  'XII'  => 'Ⅻ',
  'Y'    => 'ΎΫ¥ÝỲỶỸẎУЧŶ',
  'Z'    => 'ƵẔẐŹŻŽ',
  '1'    => 'ı',
  '3'    => '∋∃ЭǮǯƷ',
  '8'    => '☃',
  '1/4'  => '¼',
  '1/2'  => '½',
  '3/4'  => '¾',
  '4/5'  => '⅘',
  '1/6'  => '⅙',
  '5/6'  => '⅚',
  '1/8'  => '⅛',
  '3/8'  => '⅜',
  '5/8'  => '⅝',
  '7/8'  => '⅞',
  '1/3'  => '⅓',
  '2/3'  => '⅔',
  '1/5'  => '⅕',
  '2/5'  => '⅖',
  '3/5'  => '⅗',
  '<<'   => '«',
  '>>'   => '»',
  '+'    => '÷₊',
  '+-'   => '±∓',
  '-+'   => '±∓',
  '|'    => '¦ﺁﺃﺇﺍ',
  '||'   => '∥‖',
  ','    => '¸‚،˛',
  ';'    => '؛',
  ',,'   => '„',
  '-'    => '­¯−₋‐–—―',
  '--'   => '‥',
  "'"    => '´‘’‛′‵י',
  '.'    => '·∙',
  '?'    => '¿؟',
  '::'   => '∷',
  ':'    => '∶',
  '*'    => '∗',
  '='    => '₌‗',
  '('    => '₍',
  ')'    => '₎',
  '%'    => '℅',
  '"'    => '“”‟″‶˝',
  '/'    => '⁄',
);


my %rev;
while (my ($c, $b) = each(%chars)) {
  $rev{$_} = $c for split(//, $b);
}
my $unbork_re = join('|', map { quotemeta } keys %rev);
my $bork_re   = join('|', map { quotemeta } sort { length($b) <=> length($a) }
                                            keys %chars);

main() if __FILE__  eq $0;

sub main {
  my $prog = basename($0);
  my %opt;
  getopts('hr', \%opt);
  die <<EOF if $opt{h};
  usage: $prog [-r] [file [...]]
        -r: reverse (un-)borkify text
EOF

  $| = 1;
  while (<>) {
    print($opt{r} ? unborkify($_) : borkify($_));
  }
}

sub unborkify {
  my ($line) = @_;
  $line =~ s/$unbork_re/$rev{$&}/geo;
  $line;
}

sub borkify {
  my ($line) = @_;
  $line =~ s/$bork_re/substr($chars{$&}, rand(length($chars{$&})), 1)/geo;
  $line;
}

1;