Skip to content

Instantly share code, notes, and snippets.

Created September 14, 2009 10:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/186594 to your computer and use it in GitHub Desktop.
Save anonymous/186594 to your computer and use it in GitHub Desktop.
package Crypt;
use Digest::MD5 qw(md5_hex);
# コンストラクタ
sub new
{
my $this = shift;
my $self = {
'key' => 'e13k24jldfldsZDSKJFIIVKLELD93JDVWSJAHDFdfjhzhjskfhwoiqjkedjfdkjdKVKD328435284327sajudzjyhwqgxcvnfia'
};
bless $self, $this;
return $self;
}
# ID暗号化
# IN int [暗号化するID], string [ソルト文字列(半角英数6文字)]
# OUT 暗号化成功時 string [暗号化したID]
# 暗号化失敗時 undef
# サンプル
# my $encid = $CryptOBJ->encrypt($id, 'USERID');
sub encrypt
{
my $this = shift;
my $id = shift;
my $salt = shift;
# 引数チェック
if (!$id) { $TL->die('idがセットされていません'); }
if (length($salt) < 1) { $TL->die('saltがセットされていません'); }
# ID8桁16進+6桁文字列+固有文字(key)のMD5の
# 先頭6文字をとって推測不可能な6文字とする
my $unguessablestr = substr(md5_hex(sprintf('%08x',$id).$salt.$this->{'key'}), 0, 6);
# ID8桁16進と,推測不可能な6文字をつなげてエンコード
return $this->_encode(sprintf('%08x%s', $id, $unguessablestr));
}
# ID復号化
# IN string [暗号化したID], string [ソルト文字列(半角英数6文字)]
# OUT 復号化成功時 string [復号化したID]
# 復号化失敗時 undef
# サンプル
# my $id = $CryptOBJ->decrypt($encid, 'USERID');
sub decrypt
{
my $this = shift;
my $encid = shift;
my $salt = shift;
# 引数チェック
if (!$encid) { $TL->die('encidがセットされていません'); }
if (length($salt) < 1) { $TL->die('saltがセットされていません'); }
if ($encid =~ m/^[0-9a-zA-Z]+$/) {
# encidをデコード
my $idstr = $this->_decode($encid);
if ($idstr =~ m/[0-9a-f]{14}/) {
# IDを取得
my $hexid = substr($idstr, 0, 8);
my $id = hex($hexid);
# 推測不可能な6文字取得
my $checkstr = substr($idstr, 8, 6);
# 推測不可能な6文字の比較
# セットされているID8桁16進+6桁文字列+固有文字(key)のMD5
# 先頭6文字をとった推測不可能な6文字と一致すれば復号化したIDを返す
if ($checkstr eq substr(md5_hex(sprintf('%08x',$id).$salt.$this->{'key'}), 0, 6)) {
return $id;
}
}
}
return undef;
}
# エンコード
sub _encode
{
my $this = shift;
my $str = shift;
srand;
my $table = $this->_makeCodeTable();
my $salt = 0;
my @plain = split(//,$str);
my $i = 0;
for ($i = 0; $i <= $#plain; $i++) {
$plain[$i] = $table->{num}{($table->{char}{$plain[$i]} + $salt) % $table->{max}};
$salt = ($salt + $table->{char}{$plain[$i]}) % $table->{max};
}
for ($i=$#plain;$i>=0;$i--) {
$plain[$i] = $table->{num}{($table->{char}{$plain[$i]} + $salt) % $table->{max}};
$salt = ($salt + $table->{char}{$plain[$i]}) % $table->{max};
}
return join('', (@plain, $table->{num}{$salt}));
}
# デコード
sub _decode
{
my $this = shift;
my $str = shift;
my $table = $this->_makeCodeTable();
my $saltchar = chop($str);
my $salt = $table->{char}{$saltchar};
my @plain = split(//,$str);
my $i = 0;
for ($i = 0; $i<= $#plain; $i++) {
$salt = ($salt - $table->{char}{$plain[$i]} + $table->{max}) % $table->{max};
$plain[$i] = $table->{num}{($table->{char}{$plain[$i]} - $salt + $table->{max}) % $table->{max}};
}
for ($i = $#plain;$i>=0;$i--) {
$salt = ($salt - $table->{char}{$plain[$i]} + $table->{max}) % $table->{max};
$plain[$i] = $table->{num}{($table->{char}{$plain[$i]} - $salt + $table->{max}) % $table->{max}};
}
return join('', @plain);
}
# エンコード・デコード用マップテーブル作成
sub _makeCodeTable
{
my @charset = split(//,'K7WXY4abcdefgRSOrstuvLUVPGHIT56wxyzABCDlmnopqhijk0123QZEFMNJ89');
my $table = {};
for (my $i = 0; $i <= $#charset; $i++) {
$table->{char}{$charset[$i]} = $i;
$table->{num}{$i} = $charset[$i];
}
$table->{max} = $#charset + 1;
return $table;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment