yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2017/11 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
飛び交う噂にあきた
2006/07/19(Wed)19:32:37
 秋田事件。全く救いようのない連続殺人です。厳罰化の流れにより、死刑が求刑されるかもしれません。
 さて、ああいう偽装を行った動機ですが、「インターネット上で疑われていた」からであるという話が出てきています。はっきり言ってこの事件、被疑者の供述は全く信用できないのですが、だとすればインターネットの噂がなければ2件目の事件は起こらなかった可能性があるのですか。何やら意味深な話になってまいりました。
 が、これ他人事ではありません。今回に限っては噂が事実でしたが、自分や知人が犯罪に巻き込まれた際、インターネットにはたとえ無実であっても嘘八百言ってあげつらう連中は必ずいるのです。イラク人質は「自作自演」などという、冷静に考えれば明らかにあり得ないことを「ねつ造」されていましたし(しかもねつ造しておきながら謝罪の1つもなし)、いつ犯人扱い、あるいは自作自演扱いされるか分かったものではありません
 これはインターネットの大問題でしょう。例えば「自作自演」説のように、冷静に分析すればあり得ないと分かることについては、冷静な分析を行うサイトでは最初から相手にされません。しかし、質の低いサイトやコミュニティなどではこれが取り上げられ、しかもそれがインターネットそのものとみなされてしまうのです(少年犯罪が起こると、あたかも少年全体が犯罪者のような扱われ方をするのと理屈は同様)。
 もっと分かりやすく言えば、私が仮に莫大な権力を持っているとしましょう。そして、何らかの理由に基づき、中国に対して厳しい敵視政策を取ることにしたとします。無論、これには各所から異論が出るでしょう。インターネット上でも賛否に分かれて激論が交わされることになります。ここまでは普通の政策などについてもよくあることです。
 そこで、私が権力にモノを言わせて言論封殺を行うなら、まず「中国人はバカで劣等で野蛮だから、敵視して叩き潰してしまえ」などと称するサイトやコミュニティから封殺します。反対意見の人間もいくらでもいるというのに、賛成意見を持つ相手を最初に封殺するのはなぜか。無論、理由があります。
 「ゲーム脳」という言葉がありますが、ゲームと脳の働きの関係については、以前に脳科学の研究者が「ゲームをするとリラックス状態と同じになる。つまり、ゲームは休息に効果的である」という研究結果を出しています。その論文を「拡張」(というより自己都合解釈)し、「ゲーム中は脳が痴呆(認知症)と同じ状態になる」などとデタラメを言い出したのが、ゲーム脳教授というわけです。
 ちなみにゲーム脳については、「脳の観測結果と痴呆症を結びつける根拠がない」「使用した独自の測定器に科学的根拠がなく、信頼性がない」「統計学的手法を満たしていない」などの理由により、ほぼ否定されています。こんなもの否定されるのは当然ですが、問題はここからです。
 これのせいで、最初に出された論文(ゲームのリラクゼーション効果)まで同じような目で見られ、この論文を出した人は大迷惑でしょう。それどころか、脳科学者の中には「脳科学自体がインチキ学問と見られかねない」と真っ青になっている人までいるのです。「ゲーム脳」のおかげで、脳科学自体がそういうレベルの学問であるとみなされてしまう現象を危惧しているわけです。
 同じパターンのものに「サラサラの血液」があります。ごくまじめな論文が出されたのが最初でしたが、マスコミがこれを取り上げ、嘘八百をでっち上げて「エセ健康用語」にしてしまいました。しかし、多くの国民はすでにそれを見抜いていますから、「血液サラサラ」なる決まり文句に極めて大きな疑念を抱いています
 しかしながら、これのせいで最初の論文の信頼性まで下がってしまったのです。「ゲーム脳」なる脳科学理論が有名になったのに、そのことを喜ぶ脳科学者はいませんし、逆に迷惑がっている人もいます。「血液サラサラ」が有名になったのに、元の論文の執筆者がそれを喜んでいるなどという話も聞いたことがありません。
 話を戻します。中国への敵視政策を行うにあたり、自分の論を通したり、優位性を示すためには、まず「中国人はバカだから敵視すべし」と称するサイトやコミュニティを叩き潰すのが最も有効であるということがお分かりいただけたでしょうか。同じ理由で、「こういう政策を考える奴は知能が低いバカだな」などと称する反対論者は放置しておいても実害はありません。根拠に基づき、筋道を立てて反論しているサイトやコミュニティの方が余程脅威です。
 つまり、自分の背中を撃つ仲間がいる限り、自分の論を主張することすらおぼつかないのです。少年犯罪に例えれば、とある少年が「子ども監視の社会はおかしい」と主張したとして、お偉方が「監視は仕方がない。こんなに少年犯罪が起きているじゃないか」と返してくれば、ぐうの音も出なくなります。これは仲間に背中を撃たれているわけです。
 そして、ごく一部にデタラメなサイトやブログ、コミュニティがあるせいで、マスコミは「ネットなど信用ならないE級メディアだ」と言いたい放題。ネットをバカにした上、ねつ造し放題の新聞やテレビを持ち上げられても、全く反論できません。
 とにかく、いい加減な噂はご遠慮願いたいものです。さすがに「被害者面した被疑者を警察が十分に捜査せず、結果として2件目の殺人を防げなかったのは、インターネットの低信頼性コミュニティでいい加減な噂が飛び交っており、警察が母親犯人説に信頼性がないと結論付けたためではないか」などと主張すれば、当サイトがデタラメ主張サイトになってしまいますので、言わないでおきますが。

 さて、XML。XMLは色々と文字列を扱うことはできますが、バイナリデータは扱えません。データベースではBLOBなどでデータを扱えるのですが、これではXMLでデータベースのようにしてデータを保管することができません。
 が、ある日ふらふらとインターネットをさまよっていた時のこと。どこぞのサイト(たぶんXMLとは無関係の記述)曰く「データをBase64に...」。これだ。とまあ、そういう具合にひらめいてしまったのでありました。
 XMLといえばDOM、DOMといえばやはりJavaしかないでしょう(別にPHPでも構いませんが)。ということで、プラットフォームはJSPに決定。しかし、Javaには標準ではbase64ライブラリが付属していません。PHPの場合はbase64_encodeを使えば簡単に符号化できるのですが、PerlやJavaにそういうおしゃれなものは存在しないのです。
 一応、ライブラリはSunが配布しており、それを使えば符号化できなくはないようです。しかし、Sunのライブラリはひたすら著作権系の処理が面倒ですので、base64ごときの処理のために落としてくる必要もないでしょう。というわけで、この時点で自前で実装することを決定しました。
 基本はほぼPerlと同じですが、符号のせいで色々と手間取ることに。結果、以下のようなひたすら冗長なコードが完成しました。

public byte[] encodeBase64(byte data[]){
	ByteArrayOutputStream os = new ByteArrayOutputStream();
	for(int i = 0; i < data.length; i += 3){
		int len = data.length - i;	// 残りの長さ
		len = len > 3 ? 3 : len;	// しかし上限は3バイトまで

		// 必要な部分をコピー
		int bytes[] = new int[3];
		for(int x = 0; x < bytes.length; x++)
			bytes[x] = 0;	// ゼロで初期化し...
		for(int x = 0; x < len; x++){
			bytes[x] = data[i + x] & 255;	// データを代入
		}

		int list[] = new int[4];	// 変換後のデータを格納する配列

		// 1バイト目 - xxxxxx**
		list[0] = ((bytes[0]) >> 2) & 63;

		// 2バイト目 - ******xx xxxx****
		list[1] = (((bytes[0] << 8) | bytes[1]) >> 4) & 63;

		// 3バイト目 - ******** ****xxxx xx******
		list[2] = (((bytes[1] << 8) | bytes[2]) >> 6) & 63;

		// 4バイト目 - ******** ******** **xxxxxx
		list[3] = bytes[2] & 63;

		for(int p = 0; p < list.length; p++){
			int b = list[p];
			int t = 0;
			if(b == 0 && len * 8 < p * 6){	// =
				t = 0x3D;
			}else if(b <= 25){	// A-Z
				t = 0x41 + b;
			}else if(b <= 51){	// a-z
				t = 0x61 + b - 26;
			}else if(b <= 61){	// 0-9
				t = 0x30 + b - 52;
			}else if(b == 62){	// +
				t = 0x2B;
			}else if(b == 63){	// /
				t = 0x2F;
			}

			os.write(t);
		}
	}

	byte b[] = os.toByteArray();
	try{
		os.close();
	}catch(IOException e){
	}
	return b;
}

public byte[] decodeBase64(byte data[]){
	ByteArrayOutputStream os = new ByteArrayOutputStream();

	for(int i = 0; i < data.length; i += 4){
		if(data.length - i < 4)
			break;	// 数が合わない

		// 復元を行う
		int bits = 0;
		for(int x = 0; x < 4; x++){
			int b = data[i + x] & 255;	// 1バイトを取得
			int value = 0;

			if(b >= 0x41 && b <= 0x5A){	// A-Z
				value = b - 0x41;
			}else if(b >= 0x61 && b <= 0x7A){	// a-z
				value = b - 0x61 + 26;
			}else if(b >= 0x30 && b <= 0x39){	// 0-9
				value = b - 0x30 + 52;
			}else if(b == 0x2B){	// +
				value = 62;
			}else if(b == 0x2F){	// /
				value = 63;
			}else if(b == 0x3D){	// =
				break;
			}

			// データ分のビットをシフト
			bits = bits | (value << ((3 - x) * 6));
		}

		// データを3バイトにする
		os.write((bits >> 16) & 255);
		os.write((bits >> 8) & 255);
		os.write(bits & 255);
	}

	byte b[] = os.toByteArray();
	try{
		os.close();
	}catch(IOException e){
	}
	return b;
}

// 使い方
byte data[] = /*Data Input*/;
byte base64[] = encodeBase64(data);
data = decodeBase64(base64);

byte base64text[] = encodeBase64("デュアルナイト".getBytes("UTF-8"));
byte text[] = decodeBase64(base64text);
String str = new String(text , "UTF-8");
 首尾よくbase64変換が行えるようになったら、次はXMLの実装に参ります。
import="javax.servlet.http.* , javax.servlet.* , 
java.io.* , javax.xml.transform.* , javax.xml.transform.stream.* , 
javax.xml.parsers.* , org.w3c.dom.* , javax.xml.transform.dom.*"

// ...

// ファイル(face_2.gif)からデータを得る
InputStream is = new FileInputStream("webapps\\ROOT\\face_2.gif");
int avail = is.available();
byte b[] = new byte[avail];
is.read(b);
is.close();

// 構築(今回は別にネームスペースは使いませんが)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.newDocument();

// ノードを作成
Element yamicha = d.createElement("Yamicha");
d.appendChild(yamicha);

Element character = d.createElement("Character");
yamicha.appendChild(character);

Element name = d.createElement("Name");
character.appendChild(name);
name.appendChild(d.createTextNode("サーラ"));

Element classes = d.createElement("Class");
character.appendChild(classes);
classes.appendChild(d.createTextNode("デュアルナイト"));

// /Yamicha/Character/Face ノードに騎士サーラのフェイスをbase64化して登録
Element face = d.createElement("Face");
character.appendChild(face);
face.appendChild(d.createTextNode(new String(encodeBase64(b) , "ascii")));

// 保存
Transformer tf = TransformerFactory.newInstance().newTransformer();
DOMSource ds = new DOMSource();
ds.setNode(d);

StreamResult sr = new StreamResult(new File("webapps\\ROOT\\binxml.xml"));
tf.transform(ds , sr);

// 表示
response.setContentType("text/xml; charset=UTF-8");
OutputStream os = response.getOutputStream();
sr = new StreamResult(os);
tf.transform(ds , sr);
os.close();
 このXMLは以下のような構造になります。
<Yamicha>
	<Character>
		<Name>サーラ</Name>
		<Class>デュアルナイト</Class>
		<Face>(base64化したフェイス画)</Face>
	</Character>
</Yamicha>
 後はこのフェイスを復元するだけです。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse("webapps\\ROOT\\binxml.xml");

Element yamicha = (Element)d.getDocumentElement();
Element character = (Element)yamicha.getElementsByTagName("Character").item(0);
Element face = (Element)character.getElementsByTagName("Face").item(0);
String base64 = face.getFirstChild().getNodeValue();

response.setContentType("image/gif");
OutputStream os = response.getOutputStream();
os.write(decodeBase64(base64.getBytes("ascii")));
os.close();
 これで騎士サーラのフェイスが復元できます。なお、サイズは33%ほど増加しますので気をつけましょう。base64に用いられる文字は「[a-zA-Z0-9+/=]」であるため、UTF-16/32以外のほとんどの文字コードで同等に扱えますし、その上「<」や「>」、「&」のようにXML文法を混乱させるような記号が混入する恐れも全くなく、XMLで使う上では完全無欠の符号化方法となっています。
 それにしても、(まずないでしょうが)仮にXMLにUTF-32が標準化されるような事態になると、バイナリデータは532%強まで肥大化するわけですか(デュアルナイト(14) -> g2aDhYNBg4uDaYNDg2c=(ascii/20) -> UTF-32/80)。恐るべし。
 ちなみに、良く用いるバイナリデータをXMLに登録する場合、XMLをパースしてbase64デコードを行う動作を繰り返さなければならず、非常に非効率的ですから、このようなことは最初から行わないか、または最初に1度だけ読んでデータを保持しておく(CGIやPHPの場合はこの手法は困難)ようにしましょう。
カテゴリ [開発魔法][社会問題] [トラックバック 1][コメント 0]
<- 前の記事を参照 次の記事を参照 ->

Trackback(1)
バトン乱舞!(from ブログ@うにうに画像倉庫) - 2006/07/19(Wed)22:01:11
神無川雫様の所のバトンですが・・・ちゃんと確認したら、未回答が3本もありました。参考は【こちら】です。さすがに多いですねwどうやら、元が強制バトンで「脅し文句も付いている」そうですが・・・逆に回答する気がなくなってしまうような気がします。でも、「そう言う風にさ..


- Blog by yamicha.com -