このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

「URI→名前」変換の例

URIから名前への変換の例はこんな感じでしょうか(テストしてないけど)。1文字だけのエスケープと16進を使ったエスケープの2種類があるのが鬱陶しいかもしれない。


/* UriToNameConverter.java */
/* Written by: idX3amZ-hiyama の人:-) */

public class UriToNameConverter {
/* 次の1文字をエスケープ */
public static final char SINGLE_CHAR_ESCAPE = 'Z';
/* 次の2文字をUTF-8の16進表示と解釈 */
public static final char TWO_HEX_DIGIT_ESCAPE = 'X';

/* 特殊文字の小文字、内部的に使う */
private static final char SINGLE_CHAR_ESCAPE_LC = 'z';
private static final char TWO_HEX_DIGIT_ESCAPE_LC = 'x';

/* エスケープしないといけない文字達
* Rfc2396から: って、よく読んでないゾ
*/
private static char[] dangerousCharacters = {
/* reserved */
';', '/', '?' , ':', '@', '&', '=', '+', '$', ',',
/* mark */
'!', '~', '*', '\'', '(', ')',
/* added by HIYAMA */
'\\'
};

/* 16進数字の判断 */
private static boolean isHexDigit(char c) {
if (Character.isDigit(c)) return true;
int n = Character.getNumericValue(c);
return (10 <= n && n <= 15);
}
/* エスケープしないといけない文字の判断 */
private static boolean isDangerous(char c) {
for (int i = 0; i < dangerousCharacters.length; i++) {
if (dangerousCharacters[i] == c) return true;
}
return false;
}
/* コンバータ */
public static String convert(String uri) {
if (uri == null) return null;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < uri.length(); i++) {
char c = uri.charAt(i);
switch (c) {
/* 多用される'.'と'/'だけは特別扱い */
case '.':
buffer.append('-'); break;
case '/':
buffer.append('_'); break;
/* もともとあった'-'と'_'はそのまま残さないでエスケープする */
case '-': case '_':
buffer.append(SINGLE_CHAR_ESCAPE); buffer.append(c); break;
/* 特殊文字もそのまま残さないでエスケープする */
case SINGLE_CHAR_ESCAPE: case TWO_HEX_DIGIT_ESCAPE:
case SINGLE_CHAR_ESCAPE_LC: case TWO_HEX_DIGIT_ESCAPE_LC:
buffer.append(SINGLE_CHAR_ESCAPE); buffer.append(c); break;
/* URIの%エスケープはそのまま利用 */
case '%':
buffer.append('X');
if (i + 2 < uri.length()) {
char c1 = uri.charAt(++i);
char c2 = uri.charAt(++i);
if (isHexDigit(c1) && isHexDigit(c2)) {
buffer.append(c1); buffer.append(c2);
break;
}
}
// ここだけチェックして例外出しても余り意味はないけど ...
throw new IllegalArgumentException("Illegal URI string.");
default:
if (isDangerous(c)) {
/* 16進表記を使ってエスケープ */
buffer.append(TWO_HEX_DIGIT_ESCAPE);
int n1 = ((int)c) / 16;
int n2 = ((int)c) % 16;
buffer.append(Character.forDigit(n1, 16));
buffer.append(Character.forDigit(n2, 16));
} else {
/* そのまま*/
buffer.append(c);
}
break; // need not, but ...
}
}
return buffer.toString();
}
/* テスト用 */
public static void main(String[] args) {
if (0 < args.length) {
String s = args[0];
System.out.println(convert(s));
}
}
}


C:>java UriToNameConverter id:m-hiyama
idX3amZ-hiyama

C:>java UriToNameConverter http://d.hatena.ne.jp/m-hiyama
httpX3a__d-hatena-ne-jp_mZ-hiyama

C:>java UriToNameConverter hiyama@chimaira.org
hiyamaX40chimaira-org

C:>java UriToNameConverter C:\Document%20and%20Settings\Hiyama
CX3aX5cDocumentX20andX20SettingsX5cHiyama

C:>