なげぇ・・
JScript/JavaScriptではバイナリを直接扱えないので、COMの力を借ります。
半分くらいバイナリ扱う為のクラスの定義(BinaryStream)
俺々JScriptフレームワーク(wscjsfw)の一部です。
ファイル
以下コード
Object.extend = function(destination, source)
{
for (var property in source) {
destination[property] = source[property];
}
return destination;
}
String.prototype.ToCharArray = function()
{
var str = this;
var ret = [];
while(str != "")
{
ret.push(str.substring(0, 1));
str = str.substring(1);
}
return ret;
}
var SeekOrign = function(){};
SeekOrign.Begin = 1; // シークモード(ストリームの最初から)
SeekOrign.Current = 2; // シークモード(現在位置から)
SeekOrign.End = 3; //
シークモード(ストリームの最後から)
/**
* バイナリストリーム
*/
var BinaryStream = function()
{
this.stream = new ActiveXObject("ADODB.Stream");
};
Object.extend(BinaryStream.prototype, {
/**
* 内部ストリーム
*/
stream : null,
/**
* ストリームを開く
*/
Open : function()
{
this.stream.Type = 2; //adTypeText
this.stream.Charset = 'iso-8859-1';
this.stream.Open();
},
/**
* ファイルからデータをロードする
* param
* file ファイルまたはファイルパス
*/
LoadFromFile : function(file)
{
var filename = file.path ? String(file.path) : String(file);
this.stream.LoadFromFile(filename);
},
/**
* ファイルにデータを保存する
* param
* file ファイルまたはファイルパス
*/
SaveToFile : function(file)
{
var filename = file.path ? String(file.path) : String(file);
this.stream.SaveToFile(filename, 2); // adSaveCreateOverWrite
},
/**
* ストリームを閉じる
*/
Close : function()
{
this.stream.Close();
},
/**
* ストリームの終わりかを返却する
* return true:ストリームの終わり / ストリームの終わりでない
*/
IsEnd : function()
{
return this.stream.EOS;
},
/**
* サイズを取得する
* return ストリームサイズ(byte)
*/
GetSize : function()
{
return this.stream.Size;
},
/**
* 現在位置を取得する
* return 現在位置
*/
GetPosition : function()
{
return this.stream.Position;
},
/**
* ストリームからデータを読み込む
* param
* size 取得するデータのサイズ(byte)
* return 取得したデータ
*/
Read : function(size)
{
var len = this.stream.Size - this.stream.Position;
size = Math.min(len, size);
var result = [];
var _position = this.stream.Position;
this.stream.Position = 0;
this.stream.Charset = "ascii";
this.stream.Position = _position;
var s1 = this.stream.ReadText(size);
this.stream.Position = 0;
this.stream.Charset = "iso-8859-1";
this.stream.Position = _position;
var s2 = this.stream.ReadText(size);
for(var i = 0; i < s1.length; i++)
{
result.push(s1.charCodeAt(i) | (s2.charCodeAt(i) < 0x80 ? 0 : 0x80));
}
return result;
},
/**
* 現在位置からストリームから末尾までのデータを読み込む
* return 取得したデータ
*/
ReadToEnd : function()
{
return this.Read(this.stream.Size);
},
/**
* ストリームにデータを書き込む
* param
* size 書き込むデータ
*/
Write : function(data)
{
var _position = this.stream.Position;
this.stream.Position = 0;
this.stream.Charset = 'iso-8859-1';
this.stream.Position = _position;
for(var i = 0; i< data.length; i++)
{
this.stream.WriteText(String.fromCharCode(data[i] & 0xFF));
}
},
/**
* シークを行う
* param
* position シークの相対距離
* [orign] シークモード(SeekOrign)
*/
Seek : function(position, orign)
{
switch(orign)
{
case SeekOrign.Current: position += this.stream.Position; break;
case SeekOrign.End: position = this.stream.Size - position;
}
this.stream.Position = Math.max(Math.min(position, this.stream.Size), 0);
}
});
/**
* Base64クラス
*/
var Base64 = function(){};
/**
* Base64エンコードテーブル
*/
Base64.EncTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray();
/**
* Base64デコードテーブル
*/
Base64.DecTable = function(){};
// Base64デコードテーブル作成
for(var i = 0 ; i < Base64.EncTable.length; i++)
{
Base64.DecTable[Base64.EncTable[i]] = i;
}
/**
* Base64エンコード
* param
* data エンコードするバイナリデータ
* return エンコード後の文字列
*/
Base64.Encode = function(data)
{
var result = "";
var l = Math.floor(data.length / 3);
var index = 0;
for(var i = 0 ; i < l ; i++)
{
result +=
Base64.EncTable[data[index]>>2] +
Base64.EncTable[((data[index ]<<4) | (data[index+1]>>4)) & 0x3F] +
Base64.EncTable[((data[index+1]<<2) | (data[index+2]>>6)) & 0x3F] +
Base64.EncTable[(
data[index+2] ) & 0x3F];
index += 3;
}
switch(data.length % 3)
{
case 1:
result +=
Base64.EncTable[data[index]>>2] +
Base64.EncTable[(data[index ]<<4) & 0x30] + "==";
break;
case 2:
result +=
Base64.EncTable[data[index]>>2] +
Base64.EncTable[((data[index ]<<4) | (data[index+1]>>4)) & 0x3F] +
Base64.EncTable[ (data[index+1]<<2) & 0x3C] + "=";
break;
}
return result;
}
/**
* Base64デコード
* param
* data デコードする文字列
* return デコード後のバイナリデータ
*/
Base64.Decode = function(data)
{
var result = [];
var l = Math.floor(data.length / 4) - 1;
var work = data.ToCharArray();
var index = 0;
for(var i = 0 ; i < l ; i++)
{
result.push(((Base64.DecTable[work[index ]]<<2) | (Base64.DecTable[work[index+1]]>>4)) & 0xFF);
result.push(((Base64.DecTable[work[index+1]]<<4) | (Base64.DecTable[work[index+2]]>>2)) & 0xFF);
result.push(((Base64.DecTable[work[index+2]]<<6) | (Base64.DecTable[work[index+3]] )) & 0xFF);
index+=4;
}
if(work[index+2] == "=")
{
result.push(((Base64.DecTable[work[index ]]<<2) | (Base64.DecTable[work[index+1]]>>4)) & 0xFF);
}
else if(work[index+3] == "=")
{
result.push(((Base64.DecTable[work[index ]]<<2) | (Base64.DecTable[work[index+1]]>>4)) & 0xFF);
result.push(((Base64.DecTable[work[index+1]]<<4) | (Base64.DecTable[work[index+2]]>>2)) & 0xFF);
}
else
{
result.push(((Base64.DecTable[work[index ]]<<2) | (Base64.DecTable[work[index+1]]>>4)) & 0xFF);
result.push(((Base64.DecTable[work[index+1]]<<4) | (Base64.DecTable[work[index+2]]>>2)) & 0xFF);
result.push(((Base64.DecTable[work[index+2]]<<6) | (Base64.DecTable[work[index+3]] )) & 0xFF);
}
return result;
}
// テストコード
var binaryData = [1,2,3,4,5];
var base64String = Base64.Encode(binaryData); // Base64エンコード
WScript.Echo(base64String); // 表示
var decodedData = Base64.Decode(base64String) // Base64デコード
var validate = true; // 検証結果
// デコード前のデータと比較して検証
validate = binaryData.length == decodedData.length;
for(var i = 0; (i < binaryData.length) && validate; i++)
validate = binaryData[i] == decodedData[i];
WScript.Echo(validate ? "検証成功" : "検証失敗");
2010.08.06