Created
June 14, 2011 10:13
-
-
Save kencoba/1024627 to your computer and use it in GitHub Desktop.
IPSJ problem: public key encoding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 共通鍵暗号化 | |
* 仕様: | |
* キー = {キーの長さ,左循環シフト回数,キー本体} | |
* 平文 = byte列 | |
* 暗号化操作 | |
* 1.平文を、キー本体のサイズごとに分割し、部分平文を作る | |
* 2.部分平文に対し、左循環シフト回数分、左循環シフトし、シフト文を作る | |
* 3.シフト文とキー本体のxorをとり、暗号化部分バイト列を作る | |
* 4.暗号化部分バイト列を結合し、暗号化文を作る | |
*/ | |
public class PublicKeyEncoder { | |
public static void main(String[] args) { | |
byte[] key = {0x05,0x02,(byte)0xF0,(byte)0xed,0x1c}; | |
byte[] src = {(byte)0xf2,0x34,0x0c,0x5c,0x1d}; | |
System.out.print("\nkey: "); | |
print(key); | |
System.out.print("\nsrc: "); | |
print(src); | |
byte[] encoded = encode(key,src); | |
System.out.print("\nencoded:"); | |
print(encoded); | |
byte[] decoded = decode(key,encoded); | |
System.out.print("\ndecoded:"); | |
print(decoded); | |
} | |
static byte[] encode(byte[] key, byte[] src) { | |
int keyLength = key[0]; | |
int rotateSize = key[1]; | |
int[] keyBody = getKeyBody(key); | |
byte[][] splitedSrc = split(src, key.length - 2); | |
byte[] dest = new byte[src.length]; | |
int i = 0; | |
for (byte[] s : splitedSrc) { | |
byte[] encoded = | |
toByteArray(xor(keyBody, leftRotate(rotateSize, toIntArray(s)))); | |
System.arraycopy(encoded,0,dest,i,encoded.length); | |
i += encoded.length; | |
} | |
return dest; | |
} | |
static byte[] decode(byte[] key, byte[] src) { | |
int keyLength = key[0]; | |
int rotateSize = key[1]; | |
int[] keyBody = getKeyBody(key); | |
byte[][] splitedSrc = split(src, key.length - 2); | |
byte[] dest = new byte[src.length]; | |
int i = 0; | |
for (byte[] s : splitedSrc) { | |
byte[] decoded = | |
toByteArray(rightRotate(rotateSize, xor(keyBody, toIntArray(s)))); | |
System.arraycopy(decoded,0,dest,i,decoded.length); | |
i += decoded.length; | |
} | |
return dest; | |
} | |
static byte[] toByteArray(int[] src) { | |
int size = src.length / 8; | |
byte[] dest = new byte[size]; | |
for (int i = 0; i < dest.length; i++) { | |
int[] subsrc = sub(src, i * 8, 8); | |
dest[i] = toByte(subsrc); | |
} | |
return dest; | |
} | |
static int[] sub(int[] src,int start,int length) { | |
int[] dest = new int[length]; | |
System.arraycopy(src,start,dest,0,dest.length); | |
return dest; | |
} | |
static void print(int[] data) { | |
for (int d : data) { | |
System.out.print(d); | |
} | |
} | |
static void print(byte[] data) { | |
int j = 0; | |
for (int i: toIntArray(data)){ | |
System.out.print(i); | |
j++; | |
if (j > 7) { System.out.print(" "); j = 0; } | |
} | |
} | |
static void print(byte[][] data) { | |
for (byte[] d : data) { | |
print(d); | |
System.out.println(); | |
} | |
} | |
static byte[][] split(byte[] src, int eachLength) { | |
int size = src.length / eachLength; | |
size = (src.length % eachLength) != 0 ? size + 1 : size; | |
byte[][] splited = new byte[size][eachLength]; | |
// キー本体の長さで割り切れない部分の配列を生成する。 | |
if (src.length % eachLength != 0) { | |
splited[splited.length - 1] = new byte[src.length % eachLength]; | |
} | |
for (int i = 0; i < splited.length; i++) { | |
System.arraycopy(src, i * eachLength, splited[i], 0, splited[i].length); | |
} | |
return splited; | |
} | |
/** | |
* 暗号キーの本体を得る | |
**/ | |
static int[] getKeyBody(byte[] key) { | |
int bodyLength = key[0] - 2; | |
byte[] keyBody = new byte[bodyLength]; | |
System.arraycopy(key, 2, keyBody, 0, keyBody.length); | |
return toIntArray(keyBody); | |
} | |
/** | |
* xorをとる | |
**/ | |
static int[] xor(int[] bits1, int[] bits2) { | |
int length = bits1.length < bits2.length ? bits1.length : bits2.length; | |
int[] dest = new int[length]; | |
for (int i = 0; i < dest.length; i++) { | |
dest[i] = bits1[i] ^ bits2[i]; | |
} | |
return dest; | |
} | |
/** | |
* 右ローテートする | |
**/ | |
static int[] rightRotate(int rotateSize, int[] src) { | |
int[] dest = new int[src.length]; | |
System.arraycopy(src, src.length - rotateSize, dest, 0, rotateSize); | |
System.arraycopy(src, 0, dest, rotateSize, dest.length - rotateSize); | |
return dest; | |
} | |
/** | |
* 左ローテートする | |
**/ | |
static int[] leftRotate(int rotateSize, int[] src) { | |
int[] dest = new int[src.length]; | |
System.arraycopy(src, rotateSize, dest, 0, dest.length - rotateSize); | |
System.arraycopy(src, 0, dest, dest.length - rotateSize, rotateSize); | |
return dest; | |
} | |
/** | |
* 配列要素を逆転した配列を返す | |
**/ | |
static int[] reverse(int[] src) { | |
int[] dest = new int[src.length]; | |
for (int i = dest.length - 1; i >= 0; i--) { | |
dest[i] = src[src.length - 1 - i]; | |
} | |
return dest; | |
} | |
/** | |
* byte配列をint配列に変換する | |
* 最上位ビット=int[0] | |
**/ | |
static int[] toIntArray(byte[] src) { | |
int[] dest = new int[src.length * 8]; | |
for (int i = 0; i < src.length; i++) { | |
int[] d = toIntArray(src[i]); | |
System.arraycopy(d, 0, dest, i * 8, 8); | |
} | |
return dest; | |
} | |
/** | |
* byteをint配列に変換する。 | |
* 最上位ビット=int[0] | |
**/ | |
static int[] toIntArray(byte src) { | |
int[] dest = new int[8]; | |
for (int i = 0; i < dest.length; i++) { | |
dest[i] = (src & 1 << i) > 0 ? 1 : 0; | |
} | |
return reverse(dest); | |
} | |
/** | |
* int[]をbyteに変換する | |
* int[0]=最上位ビット | |
**/ | |
static byte toByte(int[] src) { | |
int[] src2 = reverse(src); | |
byte dest = 0; | |
for (int i = 0; i < 8; i++) { | |
dest |= src2[i] << i; | |
} | |
return dest; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment