16進の文字列を数値に、あるいは逆に数値を16進の文字列で表してみましょう。こういった処理はたいていのライブラリに入っています(HexToInt など)が、Java にはないようです(と思ったらありました。ご指摘いただいた方々、ありがとうございました)。そこで、どのように処理すれば良いのか考えてみました。
16進文字列とは、数値を16進数で表現した文字列です。16進の文字列を数値に変換する時、一桁なら簡単ですね。0〜9ならそのまま数値になりますし、aなら10、bなら11.....そしてfなら15、という感じです。これをプログラムにするなら、以下のような感じになるでしょう。このプログラムでは、sが16進の文字でrが結果の数値になります。
switch (s) { /* 16進一文字を数値に変換 */
case '0':
r=0;
break;
case '1':
r=1;
break;
case '2':
r=2;
break;
・
(中略)
・
case 'e':
r=14;
break;
case 'f':
r=15;
break;
}
では、次に二桁を考えてみましょう。16進二桁は00〜ff、数値としては0〜255になります。16進数では、一桁上の数字が16倍の「重み」を持っているので、一桁めは単純に一桁の処理をして、2桁めは一桁目のように数値にした後16倍すれば良いはずです。
例えば、0aとa0を考えてみます。0aの場合は、一桁目のaを数値にして10です。a0の方は、aを数値にすると10ですが、aは2桁目にあるので16倍して160。つまりa0は160になります。3桁、4桁も同様に考えると、結局以下のようなアルゴリズムで16進の文字列を数値に変換できる事になります。
1.文字列の最下位一文字を操作対象とする。 2.操作対象の文字を数値に変換(0〜15) 3.2の数値に桁数に応じた「重み」を掛け、その数値を記憶。 4.一桁上の一文字を操作対象として2に戻る。 5.最上位まで処理できたら、3の結果を合計する。 ・例 16進文字列「abcd」を数値にする。 最下位d を数値にすると13 2桁目c は12×161=192 3桁目b は11×162=2816 4桁目a は10×163=40960 よって結果は13+192+2816+40960=43981。
以上の事をまとめて、16進の文字列を渡すとその文字列が表す数値を返す関数を作れば、以下のようになるでしょう。
private int HexToInt(String str) { /* 16進文字列を数値に */
char s[];
int a,i,r;
a=1; /* 加算対象となる桁の「重み」 */
r=0; /* 結果 */
s=str.toCharArray(); /* 文字列を配列に */
for (i=str.length()-1;i>-1;i--) { /* 一字づつ取り出す */
switch (s[i]) { /* 一字取り出し文字の数値を加算 */
case '0':
r+=a*0;
break;
case '1':
r+=a*1;
break;
・
(中略)
・
case 'e':
r+=a*14;
break;
case 'f':
r+=a*15;
break;
}
a*=16; /* 一つ上の桁の「重み」を求める */
}
return r; /* 結果の数値を返す */
}
数値を16進の文字列にする、という事は16進数に「書き下す」という事です。これは、単純に数値を16進一桁(4ビット)づつ処理していけば良いでしょう。まず、最下位の1桁を得るために数値と16進0fの論理積を求めます(あるいは、数値を16で割った「余り」を求めても良い)。この結果は0〜15で、これを16進にしたものが文字列の一桁目になるわけですね。次に、2桁目を求めるために数値を1桁「ずらす」事にしましょう。すでに一桁目を求めたので、その桁を「捨てて」やれば最下位に2桁目がきます。1桁目を捨てるには、4ビット(16進一桁分)右シフト(あるいは16で除算)すれば良いでしょう。後は、1桁目と同様に0fとの論理積をとり16進一桁の文字にすれば、それが2桁目です。
以下、3桁目、4桁目、と同様にしていけば16進文字列を得る事が出来ます。今回は、数値として32ビット型整数を用いるので、この処理を8回行えば良いでしょう。関数にすると、以下のような感じです。
private String IntToHex(int n) { /* 数値を16進文字列に */
int i;
String res,rest;
res="";
for (i=0;i<8;i++) { /* 32ビット整数を16進一桁づつ変換 */
switch (n & 0xf) { /* 最下位一桁の数値を検査 */
case 10:
res+="a";
break;
case 11:
res+="b";
break;
case 12:
res+="c";
break;
case 13:
res+="d";
break;
case 14:
res+="e";
break;
case 15:
res+="f";
break;
default: /* 0〜9はそのまま数字に */
res+=String.valueOf(n & 0xf);
}
n=n>>4; /* 4ビット左シフトして一桁ずらす */
}
rest="";
for (i=7;i>-1;i--) /* 文字列を左右反転 */
rest+=res.substring(i,i+1);
return rest;
}
上の関数では、最下位の桁から順に文字列に足していっているため、そのままでは最下位が一番左端(文字列の先頭)に、最上位が右端(文字列の末端)に来てしまいます。そのため、処理が終わった後で文字列を左右反転する事にしました。
今回のプログラムには、10進表記の文字列(Int)と16進表記の文字列(Hex)を入れるテキストフィールドがあります。どちらかに適当な文字列を入れたら、「IntToHex」で10進文字列を16進文字列に、「HexToInt」で16進文字列を数値に変換してみてください。例えば、Int のテキストフィールドに「255」と入力してから「IntToHex」ボタンをクリックすると、Hexの方のテキストフィールドに255が8桁の16進の文字列として「000000ff」と表示されます。
なお、16進のアルファベットはすべて小文字にしてください。