#!perl =head1 NAME uuid-ncname - Command-line converter for UUIDs <-> NCNames =head1 SYNOPSIS uuid-ncname [-r|-n|-v VERSION|-i FILE ...] [uuid-or-ncname, ...] uuid-ncname < file =head1 OPTIONS Default behaviour: Convert the UUIDs, or Base32 NCNames passed in as arguments or via pipe, into Base64, one per line of output. Any Base64 NCNames pass through unchanged. If no arguments are passed and no input is piped in, generate a single new NCName, based on a V4 UUID. =over 4 =item -r --reverse Explicitly convert input I<from> UUID-NCName identifiers, I<back> into an ordinary UUID. (Default is to detect the form of the input.) =item -n --nocase --nc --32 Generate Base32 UUID-NCNames, rather than Base64. =item -i --input FILE Take input from the specified file. Can be passed in several times. =item -v --version 0|1 Specify identifier version. See L<Data::UUID::NCName> for details. Defaults to 1. =item --noalign Do not align the last few bits to the Base(32, 64) encoding symbols. You probably don't want this unless you need to handle mangled input. =item -h --help Print this message. =back =cut use strict; use warnings FATAL => 'all'; use Data::UUID::NCName (); use Getopt::Long (); #use Pod::Usage (); use Carp (); our $VERSION = '0.05'; Getopt::Long::Configure(qw(bundling no_ignore_case)); my $UUID = qr/^\s*(?i:urn:uuid:)? ([0-9A-Fa-f]{8}(?:-?[0-9A-Fa-f]{4}){4}[0-9A-Fa-f]{8})\s*$/x; my $B64 = qr/^\s*([A-Pa-p][0-9A-Za-z_-]{21})\s*$/; my $B32 = qr/^\s*([A-Pa-p][2-7A-Za-z]{25})\s*$/; my $ALL = qr/$UUID|$B64|$B32/; my %p = ( input => [], version => 1, noalign => 0, ); Getopt::Long::GetOptions( 'i|input=s' => $p{input}, 'r|reverse' => \$p{reverse}, 'n|nocase|nc|32' => \$p{nc}, 'u|urn' => \$p{urn}, 'v|version=i' => \$p{version}, 'noalign' => \$p{noalign}, 'h|help' => \$p{help}, ); if ($p{help}) { require Pod::Usage; exit Pod::Usage::pod2usage(0); } my @input; if (@{$p{input}}) { for my $file (@{$p{input}}) { open my $fh, $file or Carp::croak("$0: Could not read input $file: $!"); while (my $line = <$fh>) { chomp $line; unless ($line =~ $ALL) { print STDERR "$0: Don't know what to do with $line\n"; next; } push @input, $line; } } } elsif (@ARGV) { for my $x (@ARGV) { unless ($x =~ $ALL) { print STDERR "$0: Don't know what to do with $x\n"; next; } push @input, $x; } } # elsif (-t STDIN) { # while (my $line = <>) { # chomp $line; # unless ($line =~ $ALL) { # print STDERR "$0: Don't know what to do with $line\n"; # next; # } # push @input, $line; # } # } else { require UUID::Tiny; push @input, lc UUID::Tiny::create_uuid_as_string(&UUID::Tiny::UUID_V4); } my %param = ( radix => $p{nc} ? 32 : 64, version => int !!$p{version}, align => !$p{noalign}, ); for my $in (@input) { if (my ($x) = ($in =~ $UUID)) { print $p{reverse} ? "$x\n" : Data::UUID::NCName::to_ncname($x, %param) . "\n"; } elsif (($x) = ($in =~ $B64)) { $x = Data::UUID::NCName::from_ncname($x, %param); print $p{nc} && !$p{reverse} ? Data::UUID::NCName::to_ncname($x, %param) . "\n" : "$x\n"; } elsif (($x) = ($in =~ $B32)) { $x = Data::UUID::NCName::from_ncname($x, %param); print $p{reverse} ? "$x\n" : Data::UUID::NCName::to_ncname($x, %param) . "\n"; } }