@@ -18,6 +18,7 @@ public void Randomize(ref string source)
1818 {
1919 Encode ( ref source ) ;
2020 Trash ( ref source ) ;
21+ Flow ( ref source ) ;
2122 Swap ( ref source ) ;
2223 Decode ( ref source ) ;
2324 }
@@ -118,7 +119,8 @@ private void Encode(ref string str)
118119 {
119120 // Encode
120121 if ( str [ i ] == '\r ' ||
121- str [ i ] == '\n ' )
122+ str [ i ] == '\n ' ||
123+ str [ i ] == '\t ' )
122124 {
123125 continue ;
124126 }
@@ -330,12 +332,12 @@ private void Trash(ref string str)
330332 }
331333 }
332334
333- private void Swap ( ref string str )
335+ private void Flow ( ref string str )
334336 {
335337 while ( true )
336338 {
337339 // Check for tag
338- var tagIndex = str . IndexOf ( "<swap >" , StringComparison . Ordinal ) ;
340+ var tagIndex = str . IndexOf ( "<flow >" , StringComparison . Ordinal ) ;
339341 if ( tagIndex == - 1 )
340342 {
341343 break ;
@@ -345,9 +347,9 @@ private void Swap(ref string str)
345347 const int endTagLength = 7 ;
346348
347349 var afterStr = str . Substring ( tagIndex + tagLength ) ;
348-
350+
349351 // Check for close tag
350- var endTagIndex = afterStr . IndexOf ( "<swap />" , StringComparison . Ordinal ) ;
352+ var endTagIndex = afterStr . IndexOf ( "<flow />" , StringComparison . Ordinal ) ;
351353 if ( endTagIndex == - 1 )
352354 {
353355 throw new Exception ( "close tag not found" ) ;
@@ -356,90 +358,121 @@ private void Swap(ref string str)
356358 // Substring inner content
357359 var innerStr = afterStr . Substring ( 0 , endTagIndex ) ;
358360
359- // Swap blocks
360- if ( innerStr . IndexOf ( "<block>" , StringComparison . Ordinal ) != - 1 )
361- {
362- var blocks = new List < string > ( ) ;
361+ var blocks = GetCodeBlocks ( innerStr ) ;
362+
363+ var switchValues = new int [ blocks . Length ] ;
363364
364- // Find blocks
365+ // Generate switch values
366+ for ( var i = 0 ; i < switchValues . Length ; i ++ )
367+ {
365368 while ( true )
366369 {
367- // Are blocks available?
368- var blockIndex = innerStr . IndexOf ( "<block>" , StringComparison . Ordinal ) ;
369- if ( blockIndex == - 1 )
370+ var rndValue = _rnd . Next ( int . MinValue , int . MaxValue ) ;
371+
372+ if ( switchValues . All ( v => v != rndValue ) )
370373 {
371- // Add last block
372- blocks . Add ( innerStr ) ;
374+ switchValues [ i ] = rndValue ;
373375 break ;
374376 }
377+ }
378+ }
375379
376- const int blockTagLength = 7 ;
380+ // Generate variable names
381+ var switchVarName = GetVariableName ( str ) ;
382+ string exitLoopVarName ;
377383
378- // Get block's content
379- var innerBlockStr = innerStr . Substring ( 0 , blockIndex ) ;
380- blocks . Add ( innerBlockStr ) ;
384+ while ( true )
385+ {
386+ exitLoopVarName = GetVariableName ( str ) ;
381387
382- // Remove from search
383- innerStr = innerStr . Remove ( 0 , blockIndex + blockTagLength ) ;
388+ if ( exitLoopVarName != switchVarName )
389+ {
390+ break ;
384391 }
392+ }
385393
386- var swapped = new string [ blocks . Count ] ;
394+ var cases = new string [ switchValues . Length ] ;
387395
388- // Swap
389- foreach ( var block in blocks )
396+ // Fill cases
397+ for ( var i = 0 ; i < cases . Length ; i ++ )
398+ {
399+ // Last
400+ if ( i + 1 == cases . Length )
390401 {
391- // Find index to swap into
392- int swapIndex ;
393- while ( true )
394- {
395- swapIndex = _rnd . Next ( 0 , swapped . Length ) ;
396- if ( swapped [ swapIndex ] == null )
397- {
398- break ;
399- }
400- }
401-
402- swapped [ swapIndex ] = block ;
402+ cases [ i ] = $ "case { switchValues [ i ] } :{{{blocks[i]}{ exitLoopVarName } =false\u0000 break\u0000 }}";
403+ }
404+ // Not last
405+ else
406+ {
407+ cases [ i ] = $ "case { switchValues [ i ] } :{{{blocks[i]}{ switchVarName } ={ switchValues [ i + 1 ] } \u0000 break\u0000 }}<block>";
403408 }
409+ }
404410
405- // Remove old
406- str = str . Remove ( tagIndex , tagLength + endTagIndex + endTagLength ) ;
411+ // Generate output
412+ var caseOutput = cases . Aggregate ( string . Empty , ( current , c ) => current + c ) ;
413+ var output = $ "int { switchVarName } ={ switchValues [ 0 ] } \u0000 bool { exitLoopVarName } =true\u0000 while({ exitLoopVarName } ){{switch({ switchVarName } ){{<swap>{ caseOutput } <swap/>}}}}";
407414
408- // Insert new
409- var output = swapped . Aggregate ( string . Empty , ( current , s ) => current + s ) ;
410- str = str . Insert ( tagIndex , output ) ;
415+ // Remove old
416+ str = str . Remove ( tagIndex , tagLength + endTagIndex + endTagLength ) ;
417+
418+ // Insert new
419+ str = str . Insert ( tagIndex , output ) ;
420+ }
421+ }
422+
423+ private void Swap ( ref string str )
424+ {
425+ while ( true )
426+ {
427+ // Check for tag
428+ var tagIndex = str . IndexOf ( "<swap>" , StringComparison . Ordinal ) ;
429+ if ( tagIndex == - 1 )
430+ {
431+ break ;
411432 }
412- // Swap lines
413- else
433+
434+ const int tagLength = 6 ;
435+ const int endTagLength = 7 ;
436+
437+ var afterStr = str . Substring ( tagIndex + tagLength ) ;
438+
439+ // Check for close tag
440+ var endTagIndex = afterStr . IndexOf ( "<swap/>" , StringComparison . Ordinal ) ;
441+ if ( endTagIndex == - 1 )
414442 {
415- // Split
416- var lines = innerStr . Split ( new [ ] { ';' } , StringSplitOptions . RemoveEmptyEntries ) ;
417- var swapped = new string [ lines . Length ] ;
443+ throw new Exception ( "close tag not found" ) ;
444+ }
445+
446+ // Substring inner content
447+ var innerStr = afterStr . Substring ( 0 , endTagIndex ) ;
448+
449+ var blocks = GetCodeBlocks ( innerStr ) ;
450+
451+ var swapped = new string [ blocks . Length ] ;
418452
419- // Swap
420- foreach ( var line in lines )
453+ // Swap
454+ foreach ( var b in blocks )
455+ {
456+ // Find index to swap into
457+ int swapIndex ;
458+ while ( true )
421459 {
422- // Find index to swap into
423- int swapIndex ;
424- while ( true )
460+ swapIndex = _rnd . Next ( 0 , swapped . Length ) ;
461+ if ( swapped [ swapIndex ] == null )
425462 {
426- swapIndex = _rnd . Next ( 0 , swapped . Length ) ;
427- if ( swapped [ swapIndex ] == null )
428- {
429- break ;
430- }
463+ break ;
431464 }
432-
433- swapped [ swapIndex ] = line ;
434465 }
435466
436- // Remove old
437- str = str . Remove ( tagIndex , tagLength + endTagIndex + endTagLength ) ;
438-
439- // Insert new
440- var output = swapped . Aggregate ( string . Empty , ( current , s ) => current + ( s + ';' ) ) ;
441- str = str . Insert ( tagIndex , output ) ;
467+ swapped [ swapIndex ] = b ;
442468 }
469+
470+ // Remove old
471+ str = str . Remove ( tagIndex , tagLength + endTagIndex + endTagLength ) ;
472+
473+ // Insert new
474+ var output = swapped . Aggregate ( string . Empty , ( current , s ) => current + s ) ;
475+ str = str . Insert ( tagIndex , output ) ;
443476 }
444477 }
445478
@@ -463,24 +496,71 @@ private void Decode(ref string str)
463496 {
464497 str = str . Remove ( i , 1 ) . Insert ( i , ";" ) ;
465498 }
466- else
499+
500+ // Skip non-strings
501+ if ( ! insideString )
467502 {
468- // Skip non-strings
469- if ( ! insideString )
470- {
471- continue ;
472- }
503+ continue ;
504+ }
473505
474- if ( str [ i ] == '\u0001 ' )
475- {
476- str = str . Remove ( i , 1 ) . Insert ( i , "<" ) ;
477- }
478- else if ( str [ i ] == '\u0002 ' )
506+ if ( str [ i ] == '\u0001 ' )
507+ {
508+ str = str . Remove ( i , 1 ) . Insert ( i , "<" ) ;
509+ }
510+ else if ( str [ i ] == '\u0002 ' )
511+ {
512+ str = str . Remove ( i , 1 ) . Insert ( i , ">" ) ;
513+ }
514+ }
515+ }
516+
517+ private string [ ] GetCodeBlocks ( string str )
518+ {
519+ string [ ] blocks ;
520+
521+ // Swap blocks
522+ if ( str . IndexOf ( "<block>" , StringComparison . Ordinal ) != - 1 )
523+ {
524+ var blockList = new List < string > ( ) ;
525+
526+ // Find blocks
527+ while ( true )
528+ {
529+ // Are blocks available?
530+ var blockIndex = str . IndexOf ( "<block>" , StringComparison . Ordinal ) ;
531+ if ( blockIndex == - 1 )
479532 {
480- str = str . Remove ( i , 1 ) . Insert ( i , ">" ) ;
533+ // Add last block
534+ blockList . Add ( str ) ;
535+ break ;
481536 }
537+
538+ const int blockTagLength = 7 ;
539+
540+ // Get block's content
541+ var innerBlockStr = str . Substring ( 0 , blockIndex ) ;
542+ blockList . Add ( innerBlockStr ) ;
543+
544+ // Remove from search
545+ str = str . Remove ( 0 , blockIndex + blockTagLength ) ;
546+ }
547+
548+ blocks = blockList . ToArray ( ) ;
549+ }
550+ // Swap lines
551+ else
552+ {
553+ // Split
554+ var lines = str . Split ( new [ ] { ';' } , StringSplitOptions . RemoveEmptyEntries ) ;
555+ for ( var i = 0 ; i < lines . Length ; i ++ )
556+ {
557+ lines [ i ] += ';' ;
482558 }
559+
560+ blocks = lines ;
483561 }
562+
563+ return blocks ;
484564 }
485565 }
486566}
0 commit comments