#!/usr/bin/perl -w # # snbencode/decode -- snarf-n-barf encode # # Pass files back and forth between windows, by encoding them in SNB encoding # (snarf-n-barf encoding ;). This is much more compact than base64, and # ignores all embedded spaces. However, it allows high-bit chars (0xa1 to # 0xff) through, so if you use different charsets, it may screw up. # # SAMPLE: # # #!21/usr/bin/perl_-w`#`#_snbencode/decode_--_snarf-n-barf_encode`#`#_Pass_ # files_back_and_forth_between_windows,_by_encoding_them_in_SNB_encoding`#_(s # narf-n-barf_encoding_;).__This_is_much_more_compact_than_base64,_and`#_igno # res_all_embedded_spaces.__However,_it_allows_high-bit_chars_(0xa1_to`#_0xff # )_through,_so_if_you_use_different_charsets,_it_may_screw_up.``my_@passthru # !5franges_=_(0x22_.._0x5e,_0x61_.._0x7e,_0xa1_.._0xff);`my_%mappings_=_(`!0 # 90x20_=>_0x5f,!09!09!09#_space_->_!5f`!090x0a_=>_0x60!09!09!09#_nl_->_!60`) # ... etc. my @passthru_ranges = (0x22 .. 0x5e, 0x61 .. 0x7e, 0xa1 .. 0xff); my %mappings = ( 0x20 => 0x5f, # space -> _ 0x0a => 0x60 # nl -> ` ); my $escape = pack ('C', 0x21); # escape char my %ok = (); foreach my $num (0 .. 0xff) { $ok{$num} = 0; } foreach my $num (@passthru_ranges) { $ok{$num} = 1; } my $hex = '0123456789abcdef'; my %hex = (); my $i = 0; foreach (split (//, $hex)) { $hex{$i++} = $_; } my $charsperline = $ENV{'COLUMNS'}; if (!defined $charsperline) { $_ = `stty size`; /^\s*\d+\s+(\d+)\s*$/ and $charsperline = $1; } $charsperline ||= 76; $charsperline -= 2; # some wiggle room my $charcount = 0; if ((defined $ARGV[0] && $ARGV[0] eq '-d') || $0 =~ /snbdecode/) { shift; decode(); } else { encode(); } exit; sub encode { binmode STDIN; while (<>) { my @bytes = unpack ("C*", $_); my $map; foreach $_ (@bytes) { if ($ok{$_}) { out (pack ("C", $_)); } elsif (defined ($map = $mappings{$_})) { out (pack ("C", $map)); } else { out ($escape); out ($hex{($_ & 0xf0) >> 4}); out ($hex{($_ & 0x0f)}); } } } print "\n"; } sub decode { $_ = join ('', <>); s/\s+//gs; s/_/ /gs; s/\`/\n/gs; s/\!([0-9A-Fa-f]{2})/chr(hex($1))/ges; print; } sub out { my $char = shift; if ($charcount++ >= $charsperline) { print "\n"; $charcount = 0; } print $char; }