Best approach to decode Youtube cipher signature using PHP or JS

前端 未结 3 561
滥情空心
滥情空心 2020-12-04 17:17

Youtube is using cipher signature for some of the videos when the use_cipher_signature = true in the dictionary returned through http://www.youtube.com/get_vid

3条回答
  •  生来不讨喜
    2020-12-04 17:34

    I've translated to Swift 3 the Akhilesh's answer for the iOS people:

    func decryptSignature(signature:String)->String {
        return bz(signature)
    }
    func bz(_ a:String)->String {
        var arrayA = Array(a.characters)
        arrayA = cz(arrayA, 61)
        arrayA = cz(arrayA, 5)
        arrayA = arrayA.reversed()
        arrayA = Array(arrayA[2.., _ b:Int)->Array {
        var arrayA = a
        let c = a[0]
        arrayA[0] = a[b % a.count];
        arrayA[b] = c
        return arrayA
    }
    

    But I think that this algorithm isn't enough, it decrypt the signature following a specific rule. In fact , according with this perl script (youtubedown from Jamie Zawinski) the algorithm change everytime and the script collect a list of rules and algorithms during days!. So far, only three commands are used in the ciphers, so we can represent them compactly:

    # - r  = reverse the string;
    # - sN = slice from character N to the end;
    # - wN = swap 0th and Nth character.
    

    I think that the best way is to realize something like:

    func decryptChiper(_ commands:String, signature:String)->String {
        var a = Array(signature.characters)
        let cmdArray:[String]! = commands.components(separatedBy: " ")
        for cmd in cmdArray {
            var value:Int!
            if cmd.characters.count>1 {
                let secondChar = cmd.index(cmd.startIndex, offsetBy: 1)
                value = Int(cmd.substring(from:secondChar))
            }
    
            switch cmd[cmd.startIndex] {
            case "r": a = a.reversed()
            case "s":
                if let sliceFrom = value {
                    a = Array(a[sliceFrom.., _ b:Int)->Array {
        var arrayA = a
        let c = a[0]
        arrayA[0] = a[b % a.count];
        arrayA[b] = c
        return arrayA
    }
    

    Usage:

    To make an example following that Akhilesh answer:

    let signature = "D3D3434498D70C3080D9B084E48350F6519A9E9A71094.25F300BB180DDDD918EE0EBEDD174EE5D874EFEFF"
    let decryptedSign = decryptChiper("w61 w5 r s2 w69 s2 r", signature: signature )
    print(decryptedSign)
    

    Output:

    33D3494498D70C3E80D9B084E48350F6519A9E9A71094.25F300BB180DDDDD18EE0EBEDD174EE5D874E
    

提交回复
热议问题