古い記事
ランダムジャンプ
新しい記事
自分用メモ。
Perl で ASIN をぱっと見わからない文字列に可逆変換する方法を模索中。
モジュールなしで済ませたい。
(ref. [を] 日付文字列のencode/decode[2006-09-04-1])

↓今考えているやつ。未整理。
#!/usr/bin/perl
use strict;
use warnings;

my @CHARS = split(//, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
my %CHAR2NUM = map {$CHARS[$_] => $_} (0..$#CHARS);

my @AIUEO = split(//, "aiueoAIUEO_");
my %AIUEO2NUM = map {$AIUEO[$_] => $_} (0..$#AIUEO);

foreach my $asin ("4844322893", "B000EQHU6M", "0123450000") {
    my $e = aiueo_encode(asin_encode($asin));
    my $d = asin_decode(aiueo_decode($e));
    print "$asin =>(encode)=> $e =>(decode)=> $d\n";
}

sub asin_encode {
    my ($asin) = @_;
    my $sum = 0;
    foreach (reverse split(//, $asin)) {
        $sum *= @CHARS;
        $sum += $CHAR2NUM{$_};
    }
    return $sum;
}

sub asin_decode {
    my ($n) = @_;
    my $asin;
    for (1..10) {
        my $r = $n % @CHARS;
        $n = ($n - $r) / @CHARS;
        $asin .= $CHARS[$r];
    }
    return $asin;
}

sub aiueo_encode {
    my ($n) = @_;
    my $c;
    while ($n > 0) {
        my $r = $n % @AIUEO;
        $n = ($n - $r) / @AIUEO;
        $c .= $AIUEO[$r];
    }
    return $c;
}

sub aiueo_decode {
    my ($c) = @_;
    my $sum = 0;
    foreach (reverse split(//, $c)) {
        $sum *= @AIUEO;
        $sum += $AIUEO2NUM{$_};
    }
    return $sum
}

実行例:
% perl encode.pl
4844322893 =>(encode)=> uuoEIAuEI_aoIO =>(decode)=> 4844322893
B000EQHU6M =>(encode)=> oaUIAeAUeoOae_A =>(decode)=> B000EQHU6M
0123450000 =>(encode)=> ueAuOAOoi =>(decode)=> 0123450000