• ベストアンサー

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が 表示されます。(コンパイルは出来る。) うむ、分からない。どこが悪いのだろう??? 以上

  • Java
  • 回答数6
  • ありがとう数5

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

  • ベストアンサー
  • 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

  • [VB.net] StringからByte配列への変換

    皆さんこんばんは。 最近VB.NET2000でVisual Basicをはじめたのですが、どうにもString型の値をByte配列へ変換するやり方が分かりません。 VB6.0だとByte配列にStringを代入するだけでいいそうなのですが、.NETで代入しようとすると『型"String"の値を"Byteの1次元配列"に変換できません』というビルドエラーが表れてしまいます。 CByte( Mid(str,i,1) ) CLng( Mid(str,i,1) ) 他にも上記コードのように一つずつ変換しようと試みたのですが、String中のある文字がワイドバイトらしく、System.InvalidCastExceptionが表れてしまいます。 ("『"を上下反転したような文字) ワイドバイトのStringを1バイトずつ区切ってByte配列やLong配列へ格納する手法というものはありませんでしょうか。 よろしくお願いします。

  • javaの問題です。

    現在以下のようにプログラムを書いてみました。 public class Replace { public static void main(String[] args) { String str = args[0]; int num = str.indexOf(args[1]); while (num != -1){ str = ( str.substring(0, num) + args[2] + str.substring(num + args[1].length()) ); num = str.indexOf(args[1]); } System.out.println(str); } } 第一引数に第二引数が含まれていれば、それを第三引数に置換する、というものです。 上記にて第二引数が単体ならば動作するのですが、たとえば 第一引数:ABCBA 第二引数:AB 第三引数:C という風に第二引数を複数にすると、 結果がCCBAと後半のBAが変換されなくなってしまいました。 後半部分もAとBが含まれる、ということで、同じように変換出来るようにしたいのですがどのようにすればよいのでしょうか?;; どうぞよろしくお願いいたします;;

    • ベストアンサー
    • Java
  • javaのmainの引数はなぜstring[]?

    Java初心者です。 基礎的なことなのですが、質問させてください。 javaのmainメソッド定義の public static void main (String[] args) について、String[] argsの部分がjavaコマンドで実行する際に与える引数であることは 理解できました。しかし、なぜStringの配列なのかが理解できません。 実行時の引数であれば、intやdoubleも使い道があるようにも感じるので、 プログラマの好きに定義できた方が便利な気がしますし、実行時に引数を与えないなら public static void main () としてしまったほうがわかりやすいとも感じてしまいます。 実はコンパイル時や実行時に裏の見えない部分でStringの配列を使っているとか、 何か理由があるのでしょうか? mainの定義は main (String[] args)と暗記でもいいのですが、 気になったので知りたく、質問させてください。

    • ベストアンサー
    • Java
  • javaの質問です。

    JAVAの質問です。 (replaceを使わない置換) java あいういあ あ !! > !!いうい!! 上のように、引数1に引数2の文字が含まれていればその文字を引数3に置き換えるという問題を解いているのですが、思うようにいきません。引数2が1文字なら簡単なのですが、2文字・3文字の場合が全く分かりません。また、replace系も使うことはできません(replacefirstなど)。 コード例を挙げて頂けないでしょうか? 丸投げなのは重々承知しておりますが、どうかよろしくお願い致します。 class Replace{   public static void main(String args[]){     String str=args[0];     int num = str.indexOf(args[1]);     while(num != -1){       str=(str.substring(0,num)+args[2]+str.substring(num+1));       System.out.print(str);     }     System.out.println();    } } 一応こんな感じかな?と思ってコードを作ってはいるのですが、結果としては散々です。。。

    • ベストアンサー
    • Java
  • stringのreplace

    import java.io.*; public class ex51c { public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while(true) { System.out.print("String> "); String str= in.readLine(); if(str.equals("")) { break; } String res = ""; res =str.replace('a', '*') returns str.replace('e', '*') returns str.replace('i', '*') returns str.replace('o', '*') returns str.replace ('u', '*'); System.out.println(res); } } } このようなプログラムを作ってみたのですが、 コンパイル時にエラーが出ます。 どこを直せばいいのでしょうか。教えてください。

    • ベストアンサー
    • Java
  • C#で、引数における一次元と二次元配列の取り扱い

    C#について質問させていただきます。 以下のようにすればそれぞれ一次元配列と二次元配列を格納出来ますが 同時に一つの引数に収めることは無理なのでしょうか?    public static void Join(string[] Ary_str){ 本文 }    public static void Join(string[ , ] Ary_str){ 本文 } そのために、例えば以下のようにしたとします。    public static void Join(object Ary_obj){ 本文 } こうすれば一次元でも二次元でも格納出来ますが 格納された値が何次元配列なのか確認するために    Ary_obj.Rank としてもエラーになってしまいます。 (1)Objectに格納した値が何次元配列なのか確認する方法か (2)一次元でも二次元でも格納できる引数の指定方法 をご存じの方、ぜひお教え願います。><

  • 文字のバイトサイズの取得

    25バイト以上ある文字配列を25バイトまでに切り取りたいのです。 全て半角英数ならstr.substring(0 ,25)ですみますが 日本語も入っているのでsubstringが使えません。 そこで,バイト配列を使おうと思ったのですがうまくいきません。どうかお願いします。 例) String E = "AAAAAAAAAAAAAあああああああ"; byte S[] = new byte[100]; S=E.getBytes(); ByteArrayOutputStream out = new ByteArrayOutputStream(); for(int n = 0; n < 25 ; ++n){ out.write(S[n]); } System.out.println(out.toByteArray()); 結果として"AAAAAAAAAAAAAあああ"が出力されてほしい

    • ベストアンサー
    • Java
  • コマンドライン引数のチェック

    args[]ってString型の配列変数ですよね? たとえば、 コマンドライン引数で数字を受け取って演算するために Stringからint等の数値に変換するとします。 Integer.ParseInt()を使うと、もし数字ではない引数 だったときに例外処理が発生します。 事前に文字か数字がチェックする方法はあるのでしょうか? それとも例外処理で対応するしかないのでしょうか?

    • ベストアンサー
    • Java
  • バイト数の取得について

    Byteについて初心者なもので、詳しく教えて頂けませんか? 例)文字列:String str = "123あいう"; 5文字取得したい場合、     str.subString(0,5) ・・・ "123あい" と取得されますが、 5バイト取得("123あ")の場合、どのようにコーディングすればよろしいのでしょうか?

    • ベストアンサー
    • Java
  • C#のキャストについて(object→byte)

    いつもお世話になっております。C#初心者です。 「メソッドの引数として渡された値をリスト型の配列に格納する」という課題に取り組んでいますが、 変数のキャストで実行時にエラーが発生し、頭を悩ませています。 作成したコードは以下のようになっています。 public class TestClass {  private List<byte> hogeList = new List<byte>();  public void TestMethod( object hoge )  {   hogeList.Add( (byte)hoge ); ← (*)  } } 上記のメソッドをMain関数から TestClass test = new TestClass(); test.TestMethod(5); として実行すると、「hogeList」に「5」が格納される、といった動作にしたいと考えています。 しかしながら、ビルドは通るのですが、実行すると(*)の位置で止まり、 「指定されたキャストは有効ではありません。」 というメッセージが表示されます。 そこで質問なのですが、object型からbyte型にキャストする場合にはどのような記述の仕方がありますでしょうか? ご教授よろしくお願いいたします。

専門家に質問してみよう