• ベストアンサー

String型をbyte型へ

MACアドレス(16進数) 00:00:00:00:00:01 これが引数で指定される。 String str = args[0]; というものがありまして(String型)、 そのコロン:で分けられた数字部分のみをバイト配列に格納したいのですが、そのうまい方法がわかりません。お助けください。 byte mac_addr[0] = Byte.parseByte("0x".concat(str.substring(0,1))); なんて事もしてみましたが、NumberForamtExceptionが 表示されます。(コンパイルは出来る。) うむ、分からない。どこが悪いのだろう??? 以上

質問者が選んだベストアンサー

  • ベストアンサー
  • takaP-
  • ベストアンサー率79% (83/105)
回答No.1

>コロン:で分けられた数字部分のみをバイト配列に格納したいのですが、そのうまい方法がわかりません。 java.util.StringTokenizer を使いましょう。 例)StringTokenizer st=new StringTokenizer(args[0],":"); これで、st.nextToken() を呼び出せば「コロンで分けられた部分」の文字列を抽出出来ます。 例) StringTokeinzer st=new StringTokeizer(args[0],":"); String[] s=new String[st.countTokens()]; for(int i=0; i<s.length; i++){ s[i]=st.nextToken(); } >byte mac_addr[0] = Byte.parseByte("0x".concat(str.substring(0,1))); なんて事もしてみました public static byte parseByte(String s) は、文字列表現を基数10として扱うものです。 この場合は、もう1つの parseByte() 。。。 public static byte parseByte(String s, int radix) を使ってみてください。radix は基数の指定です。 例)mac_addr[0]=Byte.parseByte(str, 16); これで、基数16として数値の文字列表現(str)を byte型に変換します。 それと、Java の byte は 127 ~ -128 の値しか取りません。ご注意を。

oid7023
質問者

お礼

早速の回答ありがとうございます。 早速試してみました。 うまく文字列を引き出すことには成功いたし、大変感謝いたします。今まで数十行でやっていたことがたった数行で収まりました。気持ちいいですね。 ところで、str = "a5"で >例)mac_addr[0]=Byte.parseByte(str, 16); の時、 >それと、Java の byte は 127 ~ -128 の値しか取りません。ご注意を。 ということで、byteに格納するのは不可能となると考えました。(間違っているかな?) こうするとうまくMACアドレスを指定できるのですが mac_addr[0]=(byte)(0xa5); String型の"a5"を0xa5に指定できる方法はありませんでしょうか? 以上

すると、全ての回答が全文表示されます。

その他の回答 (5)

  • takaP-
  • ベストアンサー率79% (83/105)
回答No.6

>もっとスマートな方法があれは私も知りたい。 1.4 以上で可なら#5さんのコードが可読性も高いし良さそうな気がします。。。 StringTokenizer を使うか、または substring() などで数字部分のみを抽出してから parseInt() 後に byte にキャストする。。。ってのも、まぁ大まかには同じことなんでしょうけどね・w ちょっと目先をかえるとしたら。。。 StringBuffer sb=new StringBuffer(args[0]); int index; while((index=sb.indexOf(":"))!=-1){   sb.deleteCharAt(index); } long lg=Long.parseLong(sb.toString(),16); byte[] b=new byte[6]; for(int i=0 ; i<b.lenght ; i++){   b[i]=(byte)(lg>>(40-i*8)); } って感じで、一旦区切り文字を排除してから一括で long にしてしまって、後はシフトを使って byte 配列にぶち込むってのもありかな?(それにしても可読性悪過ぎ・w) ん、なんか話が脱線してしまいましたね。。。申し訳ない(汗

すると、全ての回答が全文表示されます。
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

String[] parts = "12:23:45:67:FF:AB".split(":"); byte[] macAddress = new byte[parts.length]; for(int i = 0 ; i < parts.length ; i++){   macAddress[i] = (byte)Integer.parseInt(parts[i], 16);   System.out.println(macAddress[i]); } でどうですか? j2sdk1.4必須ですけど・・・。

すると、全ての回答が全文表示されます。
  • nakashi
  • ベストアンサー率51% (21/41)
回答No.4

ifHex2Byteは これでいいみたい public static int ifHex2Byte(String sHex){ int iAns=0; byte bHex[] = sHex.getBytes(); iAns = Character.digit(sHex.charAt(0),16); iAns *= 16; iAns += Character.digit(sHex.charAt(1),16); return iAns; }

oid7023
質問者

お礼

ありがとうございます。 うまくいきました。 Dos窓にもキチンと格納されたMACアドレスを表示することができました。ただWindowsからフレームを送信しても MACアドレスは指定したものにならないようです。 Jpcapドキュメント http://www.goto.info.waseda.ac.jp/~fujii/jpcap/doc_ja/index.html もうしばらく格闘してみます。 以上

すると、全ての回答が全文表示されます。
  • nakashi
  • ベストアンサー率51% (21/41)
回答No.3

もっとスマートな方法があれは 私も知りたい。 import java.util.StringTokenizer; import java.lang.Character; public class Test { public static void main(String[] args) { String sMac = "12:23:45:67:FF:AB"; byte[] bMac = ufStr2Mac(sMac); for (int j=0; j<bMac.length; j++){ System.out.println(Integer.toHexString(bMac[j]).toUpperCase()); } } public static byte[] ufStr2Mac(String sMac){ byte[] bMac =new byte[6]; StringTokenizer oStringTokenizer = new StringTokenizer(sMac,":"); String sHex; for(int j=0; j<6; j++){ sHex = oStringTokenizer.nextToken(); bMac[j] = (byte)ifHex2Byte(sHex); } return bMac; } public static int ifHex2Byte(String sHex){ int iAns=0; byte bHex[] = sHex.getBytes(); Character cTmp = new Character(sHex.charAt(0)); iAns = cTmp.digit(sHex.charAt(0),16); iAns *= 16; iAns += cTmp.digit(sHex.charAt(1),16); return iAns; } }

すると、全ての回答が全文表示されます。
  • takaP-
  • ベストアンサー率79% (83/105)
回答No.2

>こうするとうまくMACアドレスを指定できるのですが mac_addr[0]=(byte)(0xa5); mac_addr[0] に本当に望む通りの値が格納されてますか? System.out.println() を使って確認してみて下さい。 ヒントは「ナローキャストは例外を発生させず、値が失われるだけ」 >>それと、Java の byte は 127 ~ -128 の値しか取りません。ご注意を。 >ということで、byteに格納するのは不可能となると考えました。 単に 127 までの値しか格納できないという事です。 仮にですけど、127 までの値しか使わないというのならば byte であってもかまわないでしょう(有り得るかどうかは別として・笑) 他にも、byte 配列に代入する際に 128 を引き、取り出す際に 128 を足すというルールに沿えるなら byte で済ませる事は可能でしょう。 けれど、特に理由が無ければ int 型にしておいた方が良いのではないですかね?(状況が解らず適当な発言ですが)

oid7023
質問者

お礼

>特に理由が無ければ 詳しい状況をご説明していないのにも関わらず、回答を頂きありがとうございます。 byteにしたい理由は、Jpcapというフレーム生成キャプチャAPIを公開されている方の指定です。 http://www.goto.info.waseda.ac.jp/~fujii/jpcap/doc_ja/index.html ここのEthernetPacketクラスのdst_macへコマンドプロンプトから受け取った引数を格納する方法がなかなかうまいこと出来ないのです。(初めからこういったほうが話は早かったかもしれませんね。) 以上

すると、全ての回答が全文表示されます。

関連するQ&A