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進のアルファベットはすべて小文字にしてください。