0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Android→WEB】円マーク・バックスラッシュのコードポイント変換(コードポイント:A5 or C2A5 ⇔ C5)

Last updated at Posted at 2020-06-07

概要

"円マーク(半角¥)"をAndroidで用いていた際に、
Windowsで"バックスラッシュ(半角/)"として、文字コードが扱われてしまった為、
円マークとバックスラッシュとの文字コードポイントの違いと、本対策について纏めました。

※ソースコードは、全てJavaを用いております。

各環境でのコードポイントの違い(円コード・バックスラッシュ)

各環境でのUTF-8で、
円コードとバックスラッシュは、以下のコードポイントが使用されます。

Windows Web
円マーク: 5C
バックスラッシュ: 5C

Mac・iOS・Android Web
円マーク: A5
バックスラッシュ: 5C

iOS・Androidネイティブアプリ
円マーク: C2A5
バックスラッシュ: 5C

[参考URL]
円マークとバックスラッシュの文字コード

対策

対策としては、円マークのコードポイントを全て、
Windows Web(コードポイント:A5 or C2A5 ⇒ C5)に寄せる対策としました。

  • A5 ⇒ C5
  • C2A5 ⇒ C5

ソースコード作成

コードポイント変換を実施するクラス(CodePointConversion.java)を作成しました。
対象のコードポイント(A5 or C2A5)を、コードポイント(C5)に変換を行います。

CodePointConversion.java
import java.util.Map;
import java.util.HashMap;
import java.lang.StringBuilder;

/**
* コードポイント変換クラス
* @author HogeHoge
*/
public class CodePointConversion {
	// コードポイント変換テーブル。KEY→VALUEのコードポイントに変換する。
	private static Map<Integer, Integer> conversion_map = new HashMap<Integer, Integer>() {
		// ¥ → \
		{put(0xA5, 0x5C);
		 put(0xC2A5, 0x5C);}
	};
	
	/**
     * コードポイント変換を行う
     * @param str コードポイント変換を行う文字列
     * @return コードポイント変換後の文字列
     */
     public static String convertCordPoint(String str) {
     	// nullチェック
		if (str == null) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		
		// 取得文字分ループ
		for(int i = 0; i < sb.length(); i++) {
			// 取得文字のコードポイントを取得
			int code_point = sb.codePointAt(i);
			
			for (Map.Entry<Integer, Integer> entry : conversion_map.entrySet()) {
		    	if (code_point == entry.getKey()) {
		    		// コードポイント変換対象の場合、コードポイント変換を実施する。
		    		String converted_char = new String(Character.toChars(entry.getValue()));
					sb.replace(i, i+1, converted_char);
				}
			}
     	}
     	
     	return sb.toString();
    }
}

テストコード作成

動作確認用のテストコードです。
入力値と出力値に関しては、実行結果をご確認ください。

CodePointConversionTest.java
import org.junit.jupiter.api.Test;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

class CodePointConversionTest {

	@Test
	void testConvertCordPoint001() {
		// 【入力値】¥¥ ※¥は半角文字。
		String input_str = new String(Character.toChars(0xA5)) + new String(Character.toChars(0xC2A5));
		// 【期待値】\\ ※最初の\はエスケープ文字。
		String expect_str = "\\\\";
		
		System.out.println("【入力値】\n" + input_str);
		System.out.println("【入力コードポイント】\n" + Integer.toHexString(input_str.codePointAt(0)) + "\n" + Integer.toHexString(input_str.codePointAt(1)));
		
		// コードポイント変換。¥→\に変換される。
		String result_str = CodePointConversion.convertCordPoint(input_str);
		
		// 出力値
		System.out.println("\n【出力値】\n" + result_str);
		System.out.println("【出力コードポイント】\n" + Integer.toHexString(result_str.codePointAt(0)) + "\n" + Integer.toHexString(result_str.codePointAt(1)));
		
		// 出力の結果確認。
		assertThat(result_str, is(expect_str));
	}

}

以下実行結果。

【入力値】
\?
【入力コードポイント】
a5
c2a5

【出力値】
\\
【出力コードポイント】
5c
5c

上記の入力値は"?"となっておりますが、Windows端末の画面の表示上の問題です。
実際には「円マーク: A5 円マーク: C2A5」の文字列が、入力値として入っております。

バックスラッシュをAndroid上で円コードとして扱う方法

今まで記載した方法は、円マークをバックスラッシュ(コードポイント:A5 or C2A5 ⇒ C5)に、
コードポイント変換する方法を記載しましたが、
Android上では、バックスラッシュ⇒円マーク(コードポイント:C5 ⇒ A5)として扱いたいケースがあると思います。

その際には、conversion_map(コードポイント変換テーブル)のKEY, VALUEを逆にする形で扱って下さい。

(例)C5のコードポイントを、A5として扱う方法。
	// コードポイント変換テーブル。KEY→VALUEのコードポイントに変換する。
	private static Map<Integer, Integer> conversion_map = new HashMap<Integer, Integer>() {
		// \ → ¥
		{put(0x5C, 0xA5);}
	};

※C5のコードポイントを、A5かC2A5として扱うかは、各環境によって変更する事。

終わりに

今回は、円マーク・バックスラッシュのコードポイント変換(コードポイント:A5 or C2A5 ⇔ C5)を行う方法を記載しましたが、
conversion_map(コードポイント変換テーブル)に、コードポイントを追加するだけで、
様々なコードポイントを変換出来るようにしてあります。

もし宜しければJavaでのコードポイント変換を行う際に、ご活用ください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?