準・究極の選択

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が
表示されます。(コンパイルは出来る。)

うむ、分からない。どこが悪いのだろう???
以上

A 回答 (6件)

>コロン:で分けられた数字部分のみをバイト配列に格納したいのですが、そのうまい方法がわかりません。



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 の値しか取りません。ご注意を。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。
早速試してみました。
うまく文字列を引き出すことには成功いたし、大変感謝いたします。今まで数十行でやっていたことがたった数行で収まりました。気持ちいいですね。

ところで、str = "a5"で
>例)mac_addr[0]=Byte.parseByte(str, 16);
の時、
>それと、Java の byte は 127 ~ -128 の値しか取りません。ご注意を。
ということで、byteに格納するのは不可能となると考えました。(間違っているかな?)
こうするとうまくMACアドレスを指定できるのですが
mac_addr[0]=(byte)(0xa5);
String型の"a5"を0xa5に指定できる方法はありませんでしょうか?
以上

お礼日時:2003/07/10 23:56

>もっとスマートな方法があれは私も知りたい。



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)

ん、なんか話が脱線してしまいましたね。。。申し訳ない(汗
    • good
    • 0

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必須ですけど・・・。
    • good
    • 0

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;
}
    • good
    • 0
この回答へのお礼

ありがとうございます。
うまくいきました。
Dos窓にもキチンと格納されたMACアドレスを表示することができました。ただWindowsからフレームを送信しても
MACアドレスは指定したものにならないようです。

Jpcapドキュメント
http://www.goto.info.waseda.ac.jp/~fujii/jpcap/d …

もうしばらく格闘してみます。

以上

お礼日時:2003/07/12 00:59

もっとスマートな方法があれは


私も知りたい。

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;
}
}
    • good
    • 0

>こうするとうまく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 型にしておいた方が良いのではないですかね?(状況が解らず適当な発言ですが)
    • good
    • 0
この回答へのお礼

>特に理由が無ければ
詳しい状況をご説明していないのにも関わらず、回答を頂きありがとうございます。
byteにしたい理由は、Jpcapというフレーム生成キャプチャAPIを公開されている方の指定です。

http://www.goto.info.waseda.ac.jp/~fujii/jpcap/d …

ここのEthernetPacketクラスのdst_macへコマンドプロンプトから受け取った引数を格納する方法がなかなかうまいこと出来ないのです。(初めからこういったほうが話は早かったかもしれませんね。)

以上

お礼日時:2003/07/11 13:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!