2 * jTsSplitter - java based mpeg2ts splitter.
3 * Copyright (C) 2009-2012 Yukikaze
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import jtssplitter.data.PATData;
10 import jtssplitter.data.PMTData;
11 import jtssplitter.data.Descriptor;
12 import jtssplitter.data.EITData;
13 import java.io.ByteArrayOutputStream;
19 public class Mpeg2TSPacket {
23 public String payload;
24 public String adaptation;
25 public byte[] header_byte;
26 public byte[] payload_byte;
27 public byte[] adaptation_byte;
28 public byte[] bPAT_payload = null;
29 //private ArrayList<TsDate> date=new ArrayList<TsDate>();
30 //date.add(new TsDate("Starter"))
32 private int starter;//0-7
33 private int transporterror;//本TSパケットの誤りを示す 1bit 8
34 private int payloadstart;//セクションの先頭バイトが入っているかどうか1bit 9
35 private int transport_priority;//1bit 10
36 private int PID = -1;//tsパケットの種類 13bit 11-23
37 private int transport_scrambled;//2bit 00is " not scrambled" 24-25
38 private int adaptation_field;//2bit 26-27 01:adaptation fieldなしでおk 10は絶対いる 11はペイロードはアダプテーションに続く00は予約
39 private int continuity_counter;//連続性(PIDごとの通し番号) 4bit 28-31
40 //ここからアダプテーションフィールド(最後まで)
41 private int adaptation_length;//8bit 32-39
42 private int discontinuity;//1bit
43 private int random_access;//1bit ランダムアクセスの開始場所となる
44 private int ES_priority;//1bit プライオリティ
45 private int five_flag;//5bit
46 private ArrayList<PATData> pat_list_now = new ArrayList<PATData>();//[0]:番組番号 [1]:PMT PID
47 private ArrayList<PATData> pat_list_all = new ArrayList<PATData>();
48 private ArrayList<PMTData> pmt_list = new ArrayList<PMTData>();//[0]番組番号 [1]テーブルID
49 private int pointer_field;//8bit adaptation fieldの次?
50 private String payload_s;
54 private int staffing_byte;//
56 public Mpeg2TSPacket() {
59 public int getPIDFirst_byte(byte[] ts) {
60 calc cal = new calc();
61 byte[] b = new byte[2];
64 return cal.byte2int(b, 3, 13);
65 //return cal.byte2int(ts,11,13);
68 public void readTS_byte(byte[] ts) {
70 * 188バイトのtsから読み出したbyteを与える
72 calc cal = new calc();
73 String tsbyte = byte2String2(ts);
74 boolean begin_payload_unit = cal.byte2int(ts, 9, 1) == 1;
75 //header = tsbyte.substring(0, 31);
76 payload = tsbyte.substring(32);
77 //starter = TSString2Int(tsbyte, 0, 8);
78 //transporterror = TSString2Int(tsbyte, 8, 1);
79 //payloadstart = TSString2Int(tsbyte, 9, 1);
80 //transport_priority = TSString2Int(tsbyte, 10, 1);
81 //PID = TSString2Int(tsbyte, 11, 13);
82 PID = cal.byte2int(ts, 11, 13);
83 adaptation_field = cal.byte2int(ts, 26, 2);
84 //continuity_counter = TSString2Int(tsbyte, 28, 4);
87 if (adaptation_field == 1) {
88 if (begin_payload_unit) {
89 pointer_field = cal.byte2int(ts, 32, 8);
90 if ((ts.length - 5 - pointer_field) < (5 + pointer_field)) {
93 payload_byte = cal.byte2subbyte(ts, 5 + pointer_field, ts.length - 5 - pointer_field);
96 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
98 } else if (adaptation_field == 3) {
99 adaptation_length = cal.byte2int(ts, 32, 8);
100 if ((adaptation_length < 184) & ((ts.length * 8 - adaptation_length * 8) > 48)) {
101 adaptation_length = adaptation_length * 8;
103 adaptation_byte = cal.byte2subbyte(ts, 4, 1 + adaptation_length / 8);
104 if (begin_payload_unit) {
105 pointer_field = cal.byte2int(ts, 40 + adaptation_length, 8);
106 if ((ts.length - 6 - (adaptation_length / 8) - pointer_field) < (6 + (adaptation_length / 8) + pointer_field)) {
109 payload_byte = cal.byte2subbyte(ts, 6 + (adaptation_length / 8) + pointer_field, ts.length - 6 - (adaptation_length / 8) - pointer_field);
112 payload_byte = cal.byte2subbyte(ts, 5 + adaptation_length / 8, ts.length - 5 - adaptation_length / 8);
118 if (payload_byte != null) {
119 if ((PID == 0) && (begin_payload_unit)) {
120 //cal.showPAT(tsbyte);
121 if (isPAT(payload_byte)){
122 pat_list_now = readPAT_byte(payload_byte);
123 if (pat_list_now.size()>0){
124 pat_list_all=pat_list_now;
126 //pat_list_all.addAll(pat_list_now);
129 for (int i = 0; i < pat_list_now.size(); i++) {
130 if ((PID == pat_list_now.get(i).PID) && (PID != 0)) {
131 pmt_list.addAll(readPMT_byte(payload_byte, pat_list_now.get(i).Program_TABLE));
138 private ArrayList<PATData> readPAT_byte(byte[] payload_temp) {
140 * payloadの文字列を入力して[intテーブル,int PID]のArrayListを返す。
144 calc cal = new calc();
145 ArrayList<PATData> program_number = new ArrayList<PATData>();
146 tableid = cal.byte2int(payload_temp, 0, 8);
147 sectionlength = cal.byte2int(payload_temp, 12, 12);//-40-32;
148 int patnum = sectionlength * 8 - 72;
149 patnum = patnum / 32;
150 for (int i = 0; i < patnum; i++) {
151 if (payload_temp.length * 8 > 64 + 32 * i + 96) {
152 if (cal.byte2int(payload_temp, 64 + 32 * i + 16, 3) == 7) {
153 PATData patd = new PATData();
154 patd.Program_TABLE = cal.byte2int(payload_temp, 64 + 32 * i, 16);
155 patd.PID = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
156 program_number.add(patd);
160 return program_number;
162 private ArrayList<PMTData> readPMT_byte(byte[] payload_temp, int PAT_TABLE) {
163 ArrayList<PMTData> pmt_t = new ArrayList<PMTData>();
164 calc cal = new calc();
165 int tableid = cal.byte2int(payload_temp, 0, 8);
166 int section_length = cal.byte2int(payload_temp, 12, 12);
167 int pcr_pid = cal.byte2int(payload_temp, 67, 13);
168 int program_info_length = cal.byte2int(payload_temp, 84, 12);
170 int cur_point = 96 + program_info_length * 8;
171 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
174 while (end != true) {
175 if (cal.byte2int(payload_temp, cur_point + 8, 3) == 7 && cal.byte2int(payload_temp, cur_point + 24, 4) == 15 && payload_temp.length * 8 > cur_point + 40) {
176 int pmt_stream_type = cal.byte2int(payload_temp, cur_point, 8);
177 int elementary_PID = cal.byte2int(payload_temp, cur_point + 11, 13);
178 //System.out.println(Integer.toString(cur_point)+" : "+Integer.toString(section_length*8));
179 int es_length = cal.byte2int(payload_temp, cur_point + 28, 12);
180 /*if (pmt_stream_type==0x02){
181 Descriptor des=new Descriptor();
182 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
183 }else if(pmt_stream_type==0x0f){
184 Descriptor des=new Descriptor();
185 Object a=des.getDescriptors(payload_temp.substring(cur_point + 40,cur_point + 40+es_length*8));
189 PMTData pmtd = new PMTData();
190 if ((pmt_stream_type == 0x02) || (pmt_stream_type == 0x0f)||(pmt_stream_type == 0x06)) {
191 pmtd.Stream_Type = pmt_stream_type;
192 pmtd.Program_Table = PAT_TABLE;
193 pmtd.Elementary_PID = elementary_PID;
194 pmtd.PCR_PID = pcr_pid;
197 cur_point = cur_point + 40 + es_length * 8;
198 //System.out.println(Integer.toString(cur_point)+" : "+Integer.toString(section_length*8));
199 if ((cur_point > section_length * 8 - 1) || (cur_point > payload_temp.length * 8 - 11)) {
202 if (payload_temp.length * 8 < cur_point + 40){
212 public ArrayList<EITData> readEIT(byte[] ts) {
213 String payload_temp = getPayload(ts);
214 int tableid = TSString2Int(payload_temp, 0, 8);
215 int section_length = TSString2Int(payload_temp, 12, 12);
216 int program_number = TSString2Int(payload_temp, 24, 16);
217 boolean current_next_indicator = (TSString2Int(payload_temp, 47, 1) == 1);
218 int section_number = TSString2Int(payload_temp, 48, 8);
220 ArrayList<EITData> ret = new ArrayList<EITData>();
221 while (curpoint < 24 + section_length * 8 - 32) {
222 EITData eitd = new EITData();
223 eitd.current_newt_indicator = current_next_indicator;
224 eitd.event_id = TSString2Int(payload_temp, curpoint, 16);
225 eitd.program_number = program_number;
226 eitd.section_number = section_number;
227 int des_len = TSString2Int(payload_temp, curpoint + 84, 12);
228 Descriptor des = new Descriptor();
229 eitd.descriptors = des.getDescriptors(payload_temp.substring(curpoint + 96, curpoint + 84 + des_len * 8));
231 curpoint = curpoint + 84 + des_len * 8;
236 private int TSString2Int(String s, int begin, int length) {
237 String st = s.substring(begin, begin + length);
238 int i = Integer.parseInt(st, 2);
242 public byte[] splitPAT_byte(byte[] ts, int p_table) {
245 * p_tableで指定された番組テーブルのみを取り出すPATを作る。
247 byte[] tbb = new byte[ts.length - 4];
248 System.arraycopy(ts, 4, tbb, 0, tbb.length);
249 if (bPAT_payload != null) {
250 if (Arrays.equals(tbb, bPAT_payload)) {
251 byte[] retb = new byte[188];
252 System.arraycopy(ts, 0, retb, 0, 4);
253 System.arraycopy(bPAT_payload, 0, retb, 4, 184);
257 calc cal = new calc();
258 header_byte = cal.byte2subbyte(ts, 0, 4);
259 byte[] pointer_byte = cal.byte2subbyte(ts, 4, 1);
260 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
261 starter = cal.byte2int(ts, 0, 8);
262 boolean begin_payload_unit = cal.byte2int(ts, 9, 1) == 1;
263 transporterror = cal.byte2int(ts, 8, 1);
264 payloadstart = cal.byte2int(ts, 9, 1);
265 transport_priority = cal.byte2int(ts, 10, 1);
266 PID = cal.byte2int(ts, 11, 13);
267 adaptation_field = cal.byte2int(ts, 26, 2);
268 continuity_counter = cal.byte2int(ts, 28, 4);
269 if (adaptation_field == 1) {
270 if (begin_payload_unit) {
271 pointer_field = cal.byte2int(ts, 32, 8);
272 if ((ts.length - 5 - pointer_field) < (5 + pointer_field)) {
275 payload_byte = cal.byte2subbyte(ts, 5 + pointer_field, ts.length - 5 - pointer_field);
278 payload_byte = cal.byte2subbyte(ts, 4, ts.length - 4);
280 } else if (adaptation_field == 3) {
281 adaptation_length = cal.byte2int(ts, 32, 8);
282 if ((adaptation_length < 184) & ((ts.length * 8 - adaptation_length * 8) > 48)) {
283 adaptation_length = adaptation_length * 8;
285 adaptation_byte = cal.byte2subbyte(ts, 4, 1 + adaptation_length / 8);
286 if (begin_payload_unit) {
287 pointer_field = cal.byte2int(ts, 40 + adaptation_length, 8);
288 if ((ts.length - 6 - (adaptation_length / 8) - pointer_field) < (6 + (adaptation_length / 8) + pointer_field)) {
291 payload_byte = cal.byte2subbyte(ts, 6 + (adaptation_length / 8) + pointer_field, ts.length - 6 - (adaptation_length / 8) - pointer_field);
294 payload_byte = cal.byte2subbyte(ts, 5 + adaptation_length / 8, ts.length - 5 - adaptation_length / 8);
299 if ((PID == 0) && (begin_payload_unit) && (payload_byte != null)) {
300 byte[] new_pointer=new byte[1];
302 if (isPAT(payload_byte)){
304 payload_byte = makePAT_byte(new_pointer, payload_byte, p_table);
305 if (payload_byte.length>0){
306 bPAT_payload = payload_byte;
310 if ((payload_byte != null)&& (begin_payload_unit)) {
311 ByteArrayOutputStream baos = new ByteArrayOutputStream(ts.length);
312 baos.write(header_byte, 0, header_byte.length);
313 baos.write(pointer_byte, 0, pointer_byte.length);
314 baos.write(payload_byte, 0, payload_byte.length);
315 for (int ir = 0; ir < 188-baos.size(); ir++) {
319 //showPAT(baos.toByteArray());
320 return baos.toByteArray();
326 private byte[] makePAT_byte(byte[] pointer_field, byte[] payload_temp, int Table) {
327 ByteArrayOutputStream baos = new ByteArrayOutputStream(payload_temp.length);
329 calc cal = new calc();
330 sectionlength = cal.byte2int(payload_temp, 12, 12); //-40-32;
331 int patnum = sectionlength * 8 - 72;
332 baos.write(payload_temp, 0, 1);
333 int new_section_length = (2 * 32 + 32 + 40) / 8;
334 baos.write(cal.joinByte((byte) cal.byte2int(payload_temp, 8, 4), (byte) (new_section_length & 0xF00), 4));
335 baos.write((byte) (new_section_length & 0xFF));
336 baos.write(payload_temp, 3, 5);
337 patnum = patnum / 32;
339 boolean alreadyadd=false;
340 for (int i = 0; i < patnum; i++) {
341 int[] pat = new int[2];
342 pat[0] = cal.byte2int(payload_temp, 64 + 32 * i, 16);
343 pat[1] = cal.byte2int(payload_temp, 32 * i + 64 + 19, 13);
345 baos.write(payload_temp, 8 + 4 * i, 4);
347 } else if ((pat[0] == Table)&&(alreadyadd==false)) {
348 baos.write(payload_temp, 8 + 4 * i, 4);
353 ByteArrayOutputStream baoscrc = new ByteArrayOutputStream(nowt + 1);
354 baoscrc.write(pointer_field[0]);
355 baoscrc.write(baos.toByteArray(), 0, baos.size());
356 byte[] crc = cal.getCRC32_byte(baoscrc.toByteArray(), 1);
357 //byte[] crc = getCRC32_byte(baoscrc.toByteArray(), 1);
358 baos.write(crc, 0, crc.length);
359 int ill3 = payload_temp.length - baos.size();
360 for (int ir = 0; ir < ill3; ir++) {
363 return baos.toByteArray();
365 public boolean isPAT(byte[] byte_tmp){
367 if ((cal.byte2int(byte_tmp,0,8)==0)&&(cal.byte2int(byte_tmp,9,3)==3)&&(cal.byte2int(byte_tmp, 40, 2)==3)){
373 public boolean isPMT(byte[] byte_tmp){
375 if ((cal.byte2int(byte_tmp,9,3)==3)&&(cal.byte2int(byte_tmp, 40, 2)==3)&&(cal.byte2int(byte_tmp,64,3)==3)&&(cal.byte2int(byte_tmp,80,4)==15)){
381 private String getCRC32(String s) {
382 return getCRC32(String2Byte(s), 1);
385 private String getCRC32(byte[] data, int offset) {
386 // x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
387 int[] g = {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
388 int[] shift_reg = new int[32];
390 byte crc32[] = new byte[4];
392 // Initialize shift register's to '1'
393 java.util.Arrays.fill(shift_reg, 1);
395 // Calculate nr of data bits, summa of bits
396 int nr_bits = (data.length - offset) * 8;
398 for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
399 // Fetch bit from bitstream
400 data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
402 if ((bit_in_byte &= 7) == 0) {
406 // Perform the shift and modula 2 addition
407 data_bit ^= shift_reg[31];
409 for (int i = 31; i > 0; i--) {
410 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
413 shift_reg[0] = data_bit;
416 for (int i = 0; i < 32; i++) {
417 crc = ((crc << 1) | (shift_reg[31 - i]));
420 for (int i = 0; i < 4; i++) {
421 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
423 String s = Long2String(crc, 32);
427 private byte[] getCRC32_byte(byte[] data, int offset) {
428 // x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
429 int[] g = {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
430 int[] shift_reg = new int[32];
432 byte crc32[] = new byte[4];
434 // Initialize shift register's to '1'
435 java.util.Arrays.fill(shift_reg, 1);
437 // Calculate nr of data bits, summa of bits
438 int nr_bits = (data.length - offset) * 8;
440 for (int bit_count = 0, bit_in_byte = 0, data_bit; bit_count < nr_bits; bit_count++) {
441 // Fetch bit from bitstream
442 data_bit = (data[offset] & 0x80 >>> (bit_in_byte++)) != 0 ? 1 : 0;
444 if ((bit_in_byte &= 7) == 0) {
448 // Perform the shift and modula 2 addition
449 data_bit ^= shift_reg[31];
451 for (int i = 31; i > 0; i--) {
452 shift_reg[i] = g[i] == 1 ? (shift_reg[i - 1] ^ data_bit) : shift_reg[i - 1];
455 shift_reg[0] = data_bit;
458 for (int i = 0; i < 32; i++) {
459 crc = ((crc << 1) | (shift_reg[31 - i]));
462 for (int i = 0; i < 4; i++) {
463 crc32[i] = (byte) (0xFF & (crc >>> ((3 - i) * 8)));
468 private String addzero(int num) {
489 StringBuffer sb = new StringBuffer();
490 for (int i = 0; i < num; i++) {
493 return sb.toString();
497 private String byte2String2(byte[] b) {
501 StringBuffer sb = new StringBuffer();
502 for (int i = 0; i < bl; i++) {
504 for (int j = 0; j < 8; j++) {
506 int ri = b[i * 8 + j] & 0xFF;
509 sb.append(Long2String(retl, 64));
511 int bl2 = b.length % 8;
512 bl2 = (bl2 - bl2 % 4) / 4;
513 for (int i = 0; i < bl2; i++) {
515 for (int j = 0; j < 4; j++) {
517 reti = reti + (b[bl * 8 + 4 * i + j] & 0xFF);
519 sb.append(Int2String(reti, 32));
521 for (int i = 0; i < (b.length % 8) % 4; i++) {
522 sb.append(Int2String(b[bl * 8 + bl2 * 4 + i] & 0xFF, 8));
524 return sb.toString();
527 private String Int2String(int num, int length) {
528 String ret = Integer.toBinaryString(num);
529 if (ret.length() < length) {
530 int it = length - ret.length();
531 for (int i = 0; i < it; i++) {
538 private String Long2String(long num, int length) {
539 String ret = Long.toBinaryString(num);
540 if (ret.length() < length) {
541 int it = length - ret.length();
542 for (int i = 0; i < it; i++) {
549 private byte[] String2Byte(String ts) {
550 //StringBuffer sb=new StringBuffer(ts);
551 int len = ts.length() - ts.length() % 8;
553 byte[] ret = new byte[len];
554 for (int i = 0; i < len; i++) {
555 String tet = ts.substring(i * 8, i * 8 + 8);
556 int itt = TSString2Int(tet, 0, 8);
562 public ArrayList<PATData> getPAT() {
566 public void setPAT(ArrayList<PATData> pat) {
571 public ArrayList<PMTData> getPMT() {
575 public void setPMT(ArrayList<PMTData> pmt) {
579 public int getPID() {
583 public String getPayload(byte[] ts) {
585 * 188バイトのtsから読み出したbyteを与える
587 String tsbyte = byte2String2(ts);
588 //header = tsbyte.substring(0, 31);
589 String ret_payload = "";
590 //starter = TSString2Int(tsbyte, 0, 8);
591 //transporterror = TSString2Int(tsbyte, 8, 1);
592 //payloadstart = TSString2Int(tsbyte, 9, 1);
593 //transport_priority = TSString2Int(tsbyte, 10, 1);
594 int pid = TSString2Int(tsbyte, 11, 13);
595 int af = TSString2Int(tsbyte, 26, 2);
596 //continuity_counter = TSString2Int(tsbyte, 28, 4);
599 ret_payload = tsbyte.substring(40);
600 } else if (af == 3) {
601 int al = TSString2Int(tsbyte, 32, 8);
602 if ((al < 184) & ((tsbyte.length() - al * 8) > 48)) {
605 ret_payload = tsbyte.substring(48 + al);
611 public byte[] getPayload_byte(byte[] ts) {
613 * 188バイトのtsから読み出したbyteを与える
615 calc cal = new calc();
616 String tsbyte = byte2String2(ts);
617 //header = tsbyte.substring(0, 31);
619 //starter = TSString2Int(tsbyte, 0, 8);
620 //transporterror = TSString2Int(tsbyte, 8, 1);
621 //payloadstart = TSString2Int(tsbyte, 9, 1);
622 //transport_priority = TSString2Int(tsbyte, 10, 1);
623 int pid = cal.byte2int(ts, 11, 13);
624 int af = cal.byte2int(ts, 26, 2);
625 //continuity_counter = TSString2Int(tsbyte, 28, 4);
628 retb = cal.byte2subbyte(ts, 5, ts.length - 5);
629 } else if (af == 3) {
630 int al = cal.byte2int(ts, 32, 8);
631 if ((al < 184) & ((ts.length * 8 - al * 8) > 48)) {
634 retb = cal.byte2subbyte(ts, 6 + al / 8, ts.length - 6 - al / 8);
640 public ArrayList<PMTData> readPMTglobal_byte(byte[] ts, int TABLE_NUM) {
641 byte[] payloadt = getPayload_byte(ts);
642 return readPMT_byte(payloadt, TABLE_NUM);
645 public void showPAT(byte[] ts){
647 showPAT(c.byte2String2(ts));
649 public void showPAT(String ts) {
650 System.out.println("先頭:" + ts.substring(0, 8));
651 System.out.println("" + ts.substring(8, 11));
652 System.out.println("PID:" + ts.substring(11, 24));
653 System.out.println("" + ts.substring(24, 32));
654 System.out.println("Adap_Len:" + ts.substring(32, 40));
655 System.out.println("TableID:" + ts.substring(40, 48));
656 System.out.println("" + ts.substring(48, 52));
657 System.out.println("len : " + ts.substring(52, 64) + "//" + Integer.toString(Integer.parseInt(ts.substring(52, 64), 2)));
658 System.out.println("TS ID:" + ts.substring(64, 80));
659 System.out.println("11:" + ts.substring(80, 82));
660 System.out.println("" + ts.substring(82, 104));
661 for (int i = 0; i < 10; i++) {
662 System.out.println(Integer.toString(i) + " : BroadNum:" + ts.substring(104 + 32 * i, 120 + 32 * i)+" (0x"+Integer.toHexString(Integer.parseInt(ts.substring(104 + 32 * i, 120 + 32 * i), 2))+") 111:"+ ts.substring(120 + 32 * i, 123 + 32 * i)+" Net/PMT PID :"+ ts.substring(123 + 32 * i, 136 + 32 * i)+" (0x"+Integer.toHexString(Integer.parseInt(ts.substring(123 + 32 * i, 136 + 32 * i), 2))+")");
664 System.out.println("Length:" + Integer.toString(ts.length()));