@@ -432,41 +432,96 @@ std::string kaitai::kstream::bytes_terminate(std::string src, char term, bool in
432432// ========================================================================
433433
434434std::string kaitai::kstream::process_xor_one (std::string data, uint8_t key) {
435+ if (key == 0 )
436+ return data;
437+
435438 size_t len = data.length ();
436439 std::string result (len, ' ' );
437440
438- for (size_t i = 0 ; i < len; i++)
441+ for (size_t i = 0 ; i < len; i++) {
439442 result[i] = data[i] ^ key;
443+ }
440444
441445 return result;
442446}
443447
444448std::string kaitai::kstream::process_xor_many (std::string data, std::string key) {
445449 size_t len = data.length ();
446450 size_t kl = key.length ();
451+ if (len == 1 )
452+ return process_xor_one (data, key[0 ]);
453+
447454 std::string result (len, ' ' );
448455
449- size_t ki = 0 ;
450456 for (size_t i = 0 ; i < len; i++) {
451- result[i] = data[i] ^ key[ki];
452- ki++;
453- if (ki >= kl)
454- ki = 0 ;
457+ result[i] = data[i] ^ key[i % kl];
455458 }
456459
457460 return result;
458461}
459462
460- std::string kaitai::kstream::process_rotate_left (std::string data, int amount) {
463+ std::string kaitai::kstream::process_rotate_left (std::string data, int amount, int groupSize = 1 ) {
464+ if (groupSize < 1 )
465+ throw std::runtime_error (" process_rotate_left: groupSize must be at least 1" );
466+
467+ amount = mod (amount, groupSize * 8 );
468+ if (amount == 0 )
469+ return data;
470+
471+ int amount_bytes = amount / 8 ;
461472 size_t len = data.length ();
462473 std::string result (len, ' ' );
463474
464- for (size_t i = 0 ; i < len; i++) {
465- uint8_t bits = data[i];
466- result[i] = (bits << amount) | (bits >> (8 - amount));
475+ if (groupSize == 1 ) {
476+ int anti_amount = 8 - amount;
477+ uint8_t translate[256 ];
478+ for (uint8_t i = 0 ; i < 256 ; i++) {
479+ translate[i] = (uint8_t )((i << amount) | (i >> anti_amount));
480+ }
481+
482+ for (size_t i = 0 ; i < len; i++) {
483+ result[i] = translate[data[i]];
484+ }
485+
486+ return result;
467487 }
468488
469- return result;
489+ if (len % groupSize != 0 )
490+ throw std::runtime_error (" process_rotate_left: data length must be a multiple of group size" );
491+
492+ if (amount % 8 == 0 ) {
493+ size_t [groupSize] indices;
494+ for (size_t i = 0 ; i < groupSize; i++) {
495+ indices[i] = (size_t )((i + amount_bytes) % groupSize);
496+ }
497+
498+ for (size_t i = 0 ; i < len; i += groupSize) {
499+ for (size_t k = 0 ; k < groupSize; k++) {
500+ result[i+k] = data[i + indices[k]];
501+ }
502+ }
503+
504+ return result;
505+ }
506+
507+ {
508+ int amount1 = amount % 8 ;
509+ int amount2 = 8 - amount1;
510+ size_t [groupSize] indices1;
511+ size_t [groupSize] indices2;
512+ for (size_t i = 0 ; i < groupSize; i++) {
513+ indices1[i] = (size_t )((i + amount_bytes) % groupSize);
514+ indices2[i] = (size_t )((i + 1 + amount_bytes) % groupSize);
515+ }
516+
517+ for (size_t i = 0 ; i < len; i += groupSize) {
518+ for (size_t k = 0 ; k < groupSize; k++) {
519+ result[i+k] = (uint8_t )((data[i + indices1[k]] << amount1) | (data[i + indices2[k]] >> amount2));
520+ }
521+ }
522+
523+ return result;
524+ }
470525}
471526
472527#ifdef KS_ZLIB
0 commit comments