2022.09.15
IT用語
エンディアン(endian)
エンディアンは、2つ以上のバイトデータを並べる順番のことです。
並べる順番によって、ビッグエンディアン、リトルエンディアンなどと呼びます。
ビッグエンディアンは、最上位バイトから順番に格納するものです。
例えば、2バイトの整数1025(16進数で0x0401)をビッグエンディアンで格納する場合、'0x40'、'0x01'の順番で格納されます。4バイトの整数0xabcd1234を格納する場合、'0xab'、'0xcd'、'0x12'、'0x34'の順番になります。
アドレス | +0 | +1 |
---|---|---|
バイトの値 | 0x40 | 0x01 |
アドレス | +0 | +1 | +2 | +3 |
---|---|---|---|---|
バイトの値 | 0xab | 0xcd | 0x12 | 0x34 |
リトルエンディアンは、最下位バイトから順番に格納するものです。
2バイトの整数1025(16進数で0x0401)をリトルエンディアンで格納する場合、'0x01'、'0x40'の順番で格納されます。4バイトの整数0xabcd1234を格納する場合、'0x34'、'0x12'、'0xcd'、'0xab'の順番になります。
アドレス | +0 | +1 |
---|---|---|
バイトの値 | 0x01 | 0x04 |
アドレス | +0 | +1 | +2 | +3 |
---|---|---|---|---|
バイトの値 | 0x34 | 0x12 | 0xcd | 0xab |
エンディアン確認用のJavaソースコード その1
Short2Bytes.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033
import java.nio.ByteBuffer; import java.nio.ByteOrder; public class Short2Bytes { public static void main( String[] args ) { // 結果を格納するbyte型配列を宣言 byte[] result; // short型の変数valueに1025(=0x0401)を代入 short value = 0x0401; // ビッグエンディアンで格納 result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array(); System.out.println( "ビッグエンディアン" ); System.out.println( result[ 0 ] ); System.out.println( result[ 1 ] ); System.out.println(); // リトルエンディアンで格納 result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array(); System.out.println( "リトルエンディアン" ); System.out.println( result[ 0 ] ); System.out.println( result[ 1 ] ); System.out.println(); // ビッグエンディアンで格納(格納順の指定なし) result = ByteBuffer.allocate( 2 ).putShort( value ).array(); System.out.println( "ビッグエンディアン(格納順の指定なし)" ); System.out.println( result[ 0 ] ); System.out.println( result[ 1 ] ); System.out.println(); } }
実行結果
ビッグエンディアン 4 1 リトルエンディアン 1 4 ビッグエンディアン(格納順の指定なし) 4 1
ここから、ソースコードを解説していきます。
001
import java.nio.ByteBuffer;
Javaのクラスライブラリの中から「java.nio.ByteBuffer」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ByteBufferクラスが利用できるようになります。
002
import java.nio.ByteOrder;
Javaのクラスライブラリの中から「java.nio.ByteOrder」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ByteOrderクラスが利用できるようになります。
004
public class Short2Bytes {
クラス名を、Short2Bytesとしています。
005
public static void main( String[] args ) {
このmainメソッドからプログラムを実行します。
006 007
// 結果を格納するbyte型配列を宣言 byte[] result;
009 010
// short型の変数valueに1025(=0x0401)を代入 short value = 0x0401;
変換元の整数valueに0x401を代入しています。ここでは、byte配列に格納した結果をわかりやすくするために16進表記で代入しています。
byteの値は、16進表記の2桁ごとに区切った値になります。この場合、「0x04」と「0x01」が格納される値になります。
shrot value=1025;としても同じ結果が得られますが、byteに変換された値の確認が少し難しくなります。
例えば、value=623とした場合、byte配列には「2」と「111」が格納されます。これを16進表記にすると「0x02」と「0x6f」です。
623を代入する式をvalue=0x026fにすれば、「0x02」と「0x6f」がどのように配列に入ったかの確認が容易になります。このソースでは、結果を10進数で表示しているので出力された結果を16進数に変換して確認する必要があります。
このソースで代入しているvalueの値は0x0401なので、2桁で区切った16進数の「0x04」と「0x01」、結果として出力された10進数の「4」と「1」が同じなので直接確認することができます。
次に紹介するソースでは、出力結果を16進表記にしているので直接確認できるようになっています。
012 013
// ビッグエンディアンで格納
result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array();
変数valueの値を、byte型の配列resultに格納しています。格納する順序は、ビッグエンディアンです。
ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。
次に、orderメソッドにByteOrder.BIG_ENDIANを渡しています。これで、格納する並び順がビッグエンディアンになります。
014 015 016 017
System.out.println( "ビッグエンディアン" );
System.out.println( result[ 0 ] );
System.out.println( result[ 1 ] );
System.out.println();
019 020
// リトルエンディアンで格納
result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array();
変数valueの値を、byte型の配列resultに格納しています。格納する順序は、リトルエンディアンです。
ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。
次に、orderメソッドにByteOrder.LITTLE_ENDIANを渡しています。これで、格納する並び順がリトルエンディアンになります。
021 022 023 024
System.out.println( "リトルエンディアン" );
System.out.println( result[ 0 ] );
System.out.println( result[ 1 ] );
System.out.println();
026 027
// ビッグエンディアンで格納(格納順の指定なし)
result = ByteBuffer.allocate( 2 ).putShort( value ).array();
変数valueの値を、byte型の配列resultに格納しています。格納する順序は、ビッグエンディアンです。
ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。
putShortメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。
最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。
orderメソッドを使わない場合はビッグエンディアンになります。
028 029 030 031
System.out.println( "ビッグエンディアン(格納順の指定なし)" );
System.out.println( result[ 0 ] );
System.out.println( result[ 1 ] );
System.out.println();
エンディアン確認用のJavaソースコード その2
Short2Bytes2.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026
import java.nio.ByteBuffer; import java.nio.ByteOrder; public class Short2Bytes2 { public static void main( String[] args ) { // 結果を格納するbyte型配列を宣言 byte[] result; // short型の変数valueに0x0a0bを代入 short value = 0x0a0b; // ビッグエンディアンで格納 result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array(); System.out.println( "ビッグエンディアン" ); System.out.println( String.format( "%02x", result[ 0 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 1 ] ) ); // 16進表記 System.out.println(); // リトルエンディアンで格納 result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array(); System.out.println( "リトルエンディアン" ); System.out.println( String.format( "%02x", result[ 0 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 1 ] ) ); // 16進表記 System.out.println(); } }
実行結果
ビッグエンディアン 0a 0b リトルエンディアン 0b 0a
ここから、ソースコードを解説していきます。
Short2Bytes.javaとの大きな違いは、出力する値を16進数にしているところなので、その出力についてだけ解説します。
015 016
System.out.println( String.format( "%02x", result[ 0 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 1 ] ) ); // 16進表記
結果のbyte型の配列resultの値を、String.formatメソッドで16進数表現の文字列に変換しています。
System.out.println( String.format( "%02x", result[ 0 ] ) );の"%02x"は、"0"埋め2桁の16進数に変換するという意味です。
これで、2桁の16進数が出力されます。
エンディアン確認用のJavaソースコード その3
Int2Bytes2.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030
import java.nio.ByteBuffer; import java.nio.ByteOrder; public class Int2Bytes2 { public static void main( String[] args ) { // 結果を格納するbyte型配列を宣言 byte[] result; // int型の変数valueに0xabcd1234を代入 int value = 0xabcd1234; // ビッグエンディアンで格納 result = ByteBuffer.allocate( 4 ).order( ByteOrder.BIG_ENDIAN ).putInt( value ).array(); System.out.println( "ビッグエンディアン" ); System.out.println( String.format( "%02x", result[ 0 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 1 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 2 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 3 ] ) ); // 16進表記 System.out.println(); // リトルエンディアンで格納 result = ByteBuffer.allocate( 4 ).order( ByteOrder.LITTLE_ENDIAN ).putInt( value ).array(); System.out.println( "リトルエンディアン" ); System.out.println( String.format( "%02x", result[ 0 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 1 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 2 ] ) ); // 16進表記 System.out.println( String.format( "%02x", result[ 3 ] ) ); // 16進表記 System.out.println(); } }
実行結果
ビッグエンディアン ab cd 12 34 リトルエンディアン 34 12 cd ab
012 013
// ビッグエンディアンで格納
result = ByteBuffer.allocate( 4 ).order( ByteOrder.BIG_ENDIAN ).putInt( value ).array();
変数valueの値を、byte型の配列resultに格納しています。格納する順序は、ビッグエンディアンです。
ByteBufferクラスのallocateメソッドで、4バイトの新しい領域を確保しています。
putIntメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。
最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。
orderメソッドで、順序を指定しない場合はビッグエンディアンになります。
以上です。