KIDCoder { public static KID encode(CertificationMode certificationMode, byte kid) throws CodingException { KID result = new KID(); final int algImpl = kid & 0x03; final int algMode = (kid & 0x0c) >> 2; final byte keysetID = (byte) ((kid & 0xf0) >>> 4); AlgorithmImplementation resultAlgImpl = null; CertificationAlgorithmMode resultAlgMode = null; switch (certificationMode) { case NO_SECURITY: resultAlgImpl = null; resultAlgMode = null; break; case RC: switch (algImpl) { case 0: resultAlgImpl = AlgorithmImplementation.ALGORITHM_KNOWN_BY_BOTH_ENTITIES; break; case 1: resultAlgImpl = AlgorithmImplementation.CRC; switch (algMode) { case 0: resultAlgMode = CertificationAlgorithmMode.CRC_16; break; case 1: resultAlgMode = CertificationAlgorithmMode.CRC_32; break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such CRC algorithm mode(raw=" + Integer.toHexString(algMode) + ")"); } break; case 3: resultAlgImpl = AlgorithmImplementation.PROPRIETARY_IMPLEMENTATIONS; break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such RC algorithm mode(raw=" + Integer.toHexString(algImpl) + ")"); } break; case CC: switch (algImpl) { case 0: resultAlgImpl = AlgorithmImplementation.ALGORITHM_KNOWN_BY_BOTH_ENTITIES; break; case 1: resultAlgImpl = AlgorithmImplementation.DES; switch (algMode) { case 0: resultAlgMode = CertificationAlgorithmMode.DES_CBC; break; case 1: resultAlgMode = CertificationAlgorithmMode.TRIPLE_DES_CBC_2_KEYS; break; case 2: resultAlgMode = CertificationAlgorithmMode.TRIPLE_DES_CBC_3_KEYS; break; case 3: resultAlgMode = CertificationAlgorithmMode.RESERVED; break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such DES algorithm mode(raw=" + Integer.toHexString(algMode) + ")"); } break; case 2: resultAlgImpl = AlgorithmImplementation.AES; switch (algMode) { case 0: resultAlgMode = CertificationAlgorithmMode.AES_CMAC; break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such AES algorithm mode(raw=" + Integer.toHexString(algMode) + ")"); } break; case 3: resultAlgImpl = AlgorithmImplementation.PROPRIETARY_IMPLEMENTATIONS; break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such algorithm implementation(raw=" + Integer.toHexString(algImpl) + ")"); } break; default: throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). No such certificationMode(raw=" + certificationMode + ")"); } if (keysetID < 0 && keysetID > 0xf) { throw new CodingException("Cannot encode KID(raw=" + Util.toHex(kid) + "). KID keySetID cannot be <0 and >15"); } result.setAlgorithmImplementation(resultAlgImpl); result.setCertificationAlgorithmMode(resultAlgMode); result.setKeysetID(keysetID); return result; }  static byte decode(KID kid); static KID encode(CertificationMode certificationMode, byte kid);  }
@Test public void test_kid_no_security() throws Exception { for (int i = 0; i < 256; i++) { final KID kid = KIDCoder.encode(CertificationMode.NO_SECURITY, (byte) (i & 0xff)); assertNull(kid.getAlgorithmImplementation()); assertNull(kid.getCertificationAlgorithmMode()); assertEquals((byte) ((i & 0xf0) >>> 4), kid.getKeysetID()); } }