<!DOCTYPE HTML>
<HTML LANG="ja">
<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>文字コード変換</TITLE>
<STYLE TYPE="text/css">
<!--
#opt::-webkit-scrollbar {display:none}
-->
</STYLE>
</HEAD>
<BODY STYLE="background-color:#CCFFFF">
<CENTER>
<B>文字コード変換</B>
<BR><BR>
<FORM ID="form" TARGET="target">
<TABLE>
<TR><TD NOWRAP>
入力文字コード:
<INPUT TYPE=TEXT ID="i_enc" SIZE=30>
<SPAN STYLE="position:relative">
<INPUT TYPE=BUTTON VALUE="選択" onClick="sel_opt(this, elem_i_enc)" STYLE="position:relative">
</SPAN>
<INPUT TYPE=BUTTON ID="in" VALUE="読み込み" onClick="input()" STYLE="margin-left:1em">
</TD></TR>
<TR><TD NOWRAP>
出力文字コード:
<INPUT TYPE=TEXT ID="o_enc" SIZE=30>
<SPAN STYLE="position:relative">
<INPUT TYPE=BUTTON VALUE="選択" onClick="sel_opt(this, elem_o_enc)" STYLE="position:relative">
</SPAN>
<SPAN STYLE="margin-left:1em">改行:</SPAN>
<SELECT ID="le">
<OPTION>LF
<OPTION>CR
<OPTION>CR+LF
</SELECT>
<INPUT TYPE=BUTTON ID="out" VALUE="書き出し" onClick="output()" STYLE="margin-left:1em">
</TD></TR>
<TR><TD>
<TEXTAREA NAME="d" ID="data" ROWS=20 COLS=80 WRAP="OFF"></TEXTAREA>
</TD></TR>
</TABLE>
<SELECT ID="opt" SIZE=9 STYLE="position:absolute; left:0; top:0; z-index:1; display:none; scrollbar-width:none; outline:none">
<OPTION>ISO-8859-1
<OPTION>ISO-2022-JP
<OPTION>Shift_JIS
<OPTION>EUC-JP
<OPTION>UTF-8
<OPTION>UTF-16BE
<OPTION>UTF-16LE
<OPTION>UTF-32BE
<OPTION>UTF-32LE
</SELECT>
</FORM>
</CENTER>
<IFRAME NAME="target" ID="frame" WIDTH=1 HEIGHT=1 SRC="about:blank" STYLE="display:none"></IFRAME>
<A ID="dl" STYLE="display:none"></A>
<SCRIPT TYPE="text/javascript">
<!--
function sel_opt(sel, enc) {
elem_sel = sel;
elem_enc = enc;
elem_opt.selectedIndex = 0;
elem_sel.parentNode.appendChild(elem_opt);
elem_opt.style.display = "";
elem_opt.focus();
}
function opt_click() {
elem_enc.value = elem_opt.value;
elem_opt.style.display = "none";
}
function opt_keydown(e) {
switch(e.keyCode) {
case 9: // Tab
if(e.shiftKey) {
elem_enc.focus();
}
else {
if(elem_enc === elem_i_enc)
elem_in.focus();
else
elem_le.focus();
}
e.preventDefault();
break;
case 13: // Enter
elem_enc.value = elem_opt.value;
// fall thru
case 27: // Esc
elem_opt.style.display = "none";
break;
}
}
function opt_blur() {
elem_opt.style.display = "none";
}
// 読み込み
function input() {
elem_in.disabled = elem_out.disabled = true;
setTimeout(enable_btn, 100);
// ファイルを開く
elem_file = document.createElement("INPUT");
elem_file.type = "FILE";
elem_file.onchange = input2;
elem_file.click();
}
function enable_btn() {
elem_in.disabled = elem_out.disabled = false;
}
function input2() {
elem_in.disabled = elem_out.disabled = true;
file_reader = new FileReader();
file_reader.onloadend = input4;
enc_val = elem_i_enc.value.trim();
switch(enc_val.toUpperCase()) {
case "UTF-16BE":
case "UTF-16LE":
case "UTF-32BE":
case "UTF-32LE":
file_reader.onload = input3s;
file_reader.readAsBinaryString(elem_file.files.item(0));
return;
}
file_reader.onload = input3;
file_reader.readAsText(elem_file.files.item(0), enc_val);
}
function input3() {
elem_data.value = file_reader.result;
elem_data.scrollTop = 0;
}
function input3s() {
var buff = file_reader.result;
var data = "";
var i = 0;
switch(enc_val.toUpperCase()) {
case "UTF-16BE":
for(; i + 1 < buff.length; i += 2)
data += String.fromCharCode((buff.charCodeAt(i) << 8) | buff.charCodeAt(i + 1));
break;
case "UTF-16LE":
for(; i + 1 < buff.length; i += 2)
data += String.fromCharCode((buff.charCodeAt(i + 1) << 8) | buff.charCodeAt(i));
break;
case "UTF-32BE":
for(; i + 3 < buff.length; i += 4) {
if(buff.charCodeAt(i) || buff.charCodeAt(i + 1)) // BMP 以外
data += String.fromCharCode(0xd800 | (((buff.charCodeAt(i + 1) & 0x1f) - 1) << 6) | (buff.charCodeAt(i + 2) >> 2),
0xdc00 | ((buff.charCodeAt(i + 2) & 0x3) << 8) | buff.charCodeAt(i + 3));
else
data += String.fromCharCode((buff.charCodeAt(i + 2) << 8) | buff.charCodeAt(i + 3));
}
break;
case "UTF-32LE":
for(; i + 3 < buff.length; i += 4) {
if(buff.charCodeAt(i + 2) || buff.charCodeAt(i + 3)) // BMP 以外
data += String.fromCharCode(0xd800 | (((buff.charCodeAt(i + 2) & 0x1f) - 1) << 6) | (buff.charCodeAt(i + 1) >> 2),
0xdc00 | ((buff.charCodeAt(i + 1) & 0x3) << 8) | buff.charCodeAt(i));
else
data += String.fromCharCode((buff.charCodeAt(i + 1) << 8) | buff.charCodeAt(i));
}
break;
}
elem_data.value = data;
elem_data.scrollTop = 0;
}
function input4() {
file_reader = undefined;
elem_in.disabled = elem_out.disabled = false;
}
// 書き出し
function output() {
var enc_val = elem_o_enc.value.trim();
switch(enc_val.toUpperCase()) {
case "UTF-16BE":
case "UTF-16LE":
case "UTF-32BE":
case "UTF-32LE":
break;
default:
elem_in.disabled = elem_out.disabled = true;
// フォームの文字エンコーディングをセットして送信
elem_form.acceptCharset = enc_val;
addEventListener("message", output2, false);
elem_form.submit();
return;
}
var data = elem_data.value;
switch(elem_le.selectedIndex) { // 改行
case 1: // CR
data = data.replace(/\n/g, "\r");
break;
case 2: // CR+LF
data = data.replace(/\n/g, "\r\n");
break;
}
var bin = "";
var c1, c2;
var i = 0;
switch(enc_val.toUpperCase()) {
case "UTF-16BE":
for(; i < data.length; i++) {
c1 = data.charCodeAt(i);
bin += String.fromCharCode(c1 >> 8) + String.fromCharCode(c1 & 0xff);
}
break;
case "UTF-16LE":
for(; i < data.length; i++) {
c1 = data.charCodeAt(i);
bin += String.fromCharCode(c1 & 0xff) + String.fromCharCode(c1 >> 8);
}
break;
case "UTF-32BE":
for(; i < data.length; i++) {
c1 = data.charCodeAt(i);
if((c1 & 0xfc00) == 0xd800) { // BMP 以外
if(++i == data.length)
break;
c2 = data.charCodeAt(i);
bin += "\0" + String.fromCharCode(((c1 & 0x3c0) >> 6) + 1)
+ String.fromCharCode(((c1 & 0x3f) << 2) | ((c2 & 0x300) >> 8))
+ String.fromCharCode(c2 & 0xff);
}
else {
bin += "\0\0" + String.fromCharCode(c1 >> 8) + String.fromCharCode(c1 & 0xff);
}
}
break;
case "UTF-32LE":
for(; i < data.length; i++) {
c1 = data.charCodeAt(i);
if((c1 & 0xfc00) == 0xd800) { // BMP 以外
if(++i == data.length)
break;
c2 = data.charCodeAt(i);
bin += String.fromCharCode(c2 & 0xff)
+ String.fromCharCode(((c1 & 0x3f) << 2) | ((c2 & 0x300) >> 8))
+ String.fromCharCode(((c1 & 0x3c0) >> 6) + 1) + "\0";
}
else {
bin += String.fromCharCode(c1 & 0xff) + String.fromCharCode(c1 >> 8) + "\0\0";
}
}
break;
}
// 変換結果をダウンロードする
elem_dl.href = "data:application/octet-stream;base64," + btoa(bin);
elem_dl.click();
}
function output2(e) {
removeEventListener("message", output2, false);
var str = e.data; // location.href
str = str.substring(str.indexOf("?") + 3).replace(/\+/g, "%20"); // ?d= の後ろを取り出し,スペースを %20 に変換
switch(elem_le.selectedIndex) { // 改行
case 0: // LF
str = str.replace(/%0[Dd]/g, "");
break;
case 1: // CR
str = str.replace(/%0[Aa]/g, "");
break;
}
// 変換結果をダウンロードする
elem_dl.href = "data:application/octet-stream," + str;
elem_dl.click();
elem_in.disabled = elem_out.disabled = false;
}
elem_form = document.getElementById("form");
elem_i_enc = document.getElementById("i_enc");
elem_in = document.getElementById("in");
elem_o_enc = document.getElementById("o_enc");
elem_le = document.getElementById("le");
elem_out = document.getElementById("out");
elem_data = document.getElementById("data");
elem_opt = document.getElementById("opt");
elem_dl = document.getElementById("dl");
// クエリー文字列は location.search で取得できるが,Firefox ではなぜか
// "data" URL のクエリー文字列を取得できない.
// Firefox でも location.href にはクエリー文字列が含まれているので,location.href を送る.
elem_form.action = "data:text/html,"
+ encodeURIComponent("<SCRIPT TYPE='text/javascript'>parent.postMessage(location.href, '*')</SCRIPT>");
elem_opt.onclick = opt_click;
elem_opt.onkeydown = opt_keydown;
elem_opt.onblur = opt_blur;
elem_i_enc.focus();
// Firefox でページを再ロードしたときのため
elem_form.reset();
elem_in.disabled = elem_out.disabled = false;
//-->
</SCRIPT>
</BODY>
</HTML>
|