@@ -7,7 +7,7 @@ namespace YoutubeExtractor
77{
88 internal static class Decipherer
99 {
10- public static string DecipherOperations ( string cipherVersion )
10+ public static string DecipherWithVersion ( string cipher , string cipherVersion )
1111 {
1212 string jsUrl = string . Format ( "http://s.ytimg.com/yts/jsbin/html5player-{0}.js" , cipherVersion ) ;
1313 string js = HttpHelper . DownloadString ( jsUrl ) ;
@@ -20,15 +20,18 @@ public static string DecipherOperations(string cipherVersion)
2020 var funcBody = Regex . Match ( js , funcPattern ) . Groups [ "brace" ] . Value ; //Entire sig function
2121 var lines = funcBody . Split ( ';' ) ; //Each line in sig function
2222
23- string id_Reverse = "" , id_Slice = "" , id_CharSwap = "" ; //Hold name for each method
23+ string id_Reverse = "" , id_Slice = "" , id_CharSwap = "" ; //Hold name for each cipher method
2424 string functionIdentifier = "" ;
2525 string operations = "" ;
2626
27- //Match the code with each function. Only runs till all three are defined.
28- foreach ( var line in lines . Skip ( 1 ) . Take ( lines . Length - 2 ) )
27+
28+ foreach ( var line in lines . Skip ( 1 ) . Take ( lines . Length - 2 ) ) //Matchs the funcBody with each cipher method. Only runs till all three are defined.
2929 {
3030 if ( ! string . IsNullOrEmpty ( id_Reverse ) && ! string . IsNullOrEmpty ( id_Slice ) &&
31- ! string . IsNullOrEmpty ( id_CharSwap ) ) { break ; } //Break out if all defined.
31+ ! string . IsNullOrEmpty ( id_CharSwap ) )
32+ {
33+ break ; //Break loop if all three cipher methods are defined
34+ }
3235
3336 functionIdentifier = getFunctionFromLine ( line ) ;
3437 string re_Reverse = string . Format ( @"{0}:\bfunction\b\(\w+\)" , functionIdentifier ) ; //Regex for reverse (one parameter)
@@ -37,13 +40,19 @@ public static string DecipherOperations(string cipherVersion)
3740
3841 Match me ;
3942 if ( ( me = Regex . Match ( js , re_Reverse ) ) . Success )
40- { id_Reverse = functionIdentifier ; } //If def matched the regex for reverse then the current function is a defined as the reverse cipher
43+ {
44+ id_Reverse = functionIdentifier ; //If def matched the regex for reverse then the current function is a defined as the reverse
45+ }
4146
4247 if ( ( me = Regex . Match ( js , re_Slice ) ) . Success )
43- { id_Slice = functionIdentifier ; } //If def matched the regex for slice then the current function is defined as the slice cipher.
48+ {
49+ id_Slice = functionIdentifier ; //If def matched the regex for slice then the current function is defined as the slice.
50+ }
4451
4552 if ( ( me = Regex . Match ( js , re_Swap ) ) . Success )
46- { id_CharSwap = functionIdentifier ; } //If def matched the regex for charSwap then the current function is defined as swap cipher.
53+ {
54+ id_CharSwap = functionIdentifier ; //If def matched the regex for charSwap then the current function is defined as swap.
55+ }
4756
4857 }
4958
@@ -53,35 +62,30 @@ public static string DecipherOperations(string cipherVersion)
5362 functionIdentifier = getFunctionFromLine ( line ) ;
5463
5564 if ( ( m = Regex . Match ( line , @"\(\w+,(?<index>\d+)\)" ) ) . Success && functionIdentifier == id_CharSwap )
56- { operations += "w" + m . Groups [ "index" ] . Value + " " ; } //Character swap regex appears to be the same as before
65+ {
66+ operations += "w" + m . Groups [ "index" ] . Value + " " ; //operation is a swap (w)
67+ }
5768
5869 if ( ( m = Regex . Match ( line , @"\(\w+,(?<index>\d+)\)" ) ) . Success && functionIdentifier == id_Slice )
59- { operations += "s" + m . Groups [ "index" ] . Value + " " ; } //Slice appears to have changed the index location???
60- //Could be wrong and the regex needs improving, seems to work on the latest algorithm though.
70+ {
71+ operations += "s" + m . Groups [ "index" ] . Value + " " ; //operation is a slice
72+ }
6173
62- if ( functionIdentifier == id_Reverse )
63- { operations += "r " ; } //Reverse operation, no regex required
74+ if ( functionIdentifier == id_Reverse ) //No regex required for reverse (reverse method has no parameters)
75+ {
76+ operations += "r " ; //operation is a reverse
77+ }
6478
6579 }
6680
6781 operations = operations . Trim ( ) ;
68- return operations ;
6982
83+ return DecipherWithOperations ( cipher , operations ) ;
7084 }
7185
72- public static string DecipherWithOperations ( string cipher , string operations )
73- {
74- if ( string . IsNullOrEmpty ( operations ) )
75- { throw new NotImplementedException ( "No valid cipher operations found." ) ; }
76-
77- return operations . Split ( new [ ] { " " } , StringSplitOptions . RemoveEmptyEntries )
78- . Aggregate ( cipher , ApplyOperation ) ;
79- }
80-
81-
8286 private static string getFunctionFromLine ( string currentLine )
8387 {
84- Regex matchFunctionReg = new Regex ( @"\w+\.(?<functionID>\w+)\(" ) ; //lc.ac(b,c) want ac .
88+ Regex matchFunctionReg = new Regex ( @"\w+\.(?<functionID>\w+)\(" ) ; //lc.ac(b,c) want the ac part .
8589 Match rgMatch = matchFunctionReg . Match ( currentLine ) ;
8690 string matchedFunction = rgMatch . Groups [ "functionID" ] . Value ;
8791 return matchedFunction ; //return 'ac'
@@ -111,6 +115,11 @@ private static string ApplyOperation(string cipher, string op)
111115 }
112116 }
113117
118+ private static string DecipherWithOperations ( string cipher , string operations )
119+ {
120+ return operations . Split ( new [ ] { " " } , StringSplitOptions . RemoveEmptyEntries )
121+ . Aggregate ( cipher , ApplyOperation ) ;
122+ }
114123
115124 private static int GetOpIndex ( string op )
116125 {
@@ -129,4 +138,4 @@ private static string SwapFirstChar(string cipher, int index)
129138 return builder . ToString ( ) ;
130139 }
131140 }
132- }
141+ }
0 commit comments