-
-
[原创]国赛babytree wp
-
2022-6-5 16:55 3146
-
<!-- * @Author: wenling * @Date: 2022-06-03 19:18:11 * @LastEditors: wenling * @LastEditTime: 2022-06-05 16:39:50 * @Description: 请填写简介 -->
2022国赛babytree wp
题目给了一个txt文件,里面是swift的抽象语法树
文本很长而且是我不熟悉的swift语言,所以先了解一下swift的抽象语法树吧
swift开发环境搭建:https://www.fatbobman.com/posts/swift-in-linux/
例子:
1 | var str = "hello" |
使用如下命令将switf文件转换为ast文件
1 | swiftc - dump - ast hello.swift |
如图就是一个初始化语句的ast结构:
- pattern_binding_decl:初始化语句
- pattern_named type='String' 'str':变量名称
- value="hello":变量值
在题目给出的ast中,有类似的结构
1 2 3 4 5 6 7 8 | (pattern_binding_decl range = [re.swift: 18 : 5 - line: 18 : 15 ] (pattern_named type = 'String' 'key' ) Original init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * ) Processed init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * )) (var_decl range = [re.swift: 18 : 9 - line: 18 : 9 ] "key" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
所以这一块结构的意思就是:
1 | var key = "345y" |
再看一个例子:
1 2 3 4 | var num = 10 if num = = 10 { num = 100 } |
if语句
- if_stmt:if语句
- declref_expr:比较的对象
- integer_literal_expr:比较的值
赋值语句
- assign_expr:赋值语句
- declref_expr:赋值的对象
- integer_literal_expr:赋值的值
其他的对应关系就不列出了,可以自己写代码对照
1 2 3 4 5 6 7 8 9 10 11 12 13 | (call_expr type = '()' location = re.swift: 20 : 5 range = [re.swift: 20 : 5 - line: 20 : 17 ] nothrow (declref_expr type = '(Any..., String, String) -> ()' location = re.swift: 20 : 5 range = [re.swift: 20 : 5 - line: 20 : 5 ] decl = Swift.( file ). print (_:separator:terminator:) function_ref = single) (argument_list labels = _:separator:terminator: (argument (vararg_expansion_expr implicit type = 'Any...' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] (array_expr implicit type = 'Any...' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] initializer = * * NULL * * (erasure_expr implicit type = 'Any' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] (declref_expr type = 'Bool' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] decl = re.( file ).top - level code.result@re.swift: 19 : 9 function_ref = unapplied))))) (argument label = separator (default_argument_expr implicit type = 'String' location = re.swift: 20 : 10 range = [re.swift: 20 : 10 - line: 20 : 10 ] default_args_owner = Swift.( file ). print (_:separator:terminator:) param = 1 )) (argument label = terminator (default_argument_expr implicit type = 'String' location = re.swift: 20 : 10 range = [re.swift: 20 : 10 - line: 20 : 10 ] default_args_owner = Swift.( file ). print (_:separator:terminator:) param = 2 )) ))))))) |
- call_expr:函数调用
- declrefexpr:调用的函数,decl=Swift.(file).print(:separator:terminator:),这里调用的是print函数
- argument:参数
1 | print (result) |
这段代码中,调用了print函数,打印的是result的值,result是Bool类型的数据,所以程序会输出true或者false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (pattern_binding_decl range = [re.swift: 19 : 5 - line: 19 : 33 ] (pattern_named type = 'Bool' 'result' ) Original init: (call_expr type = 'Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 33 ] nothrow (declref_expr type = '(String, String) -> Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 18 ] decl = re.( file ).check@re.swift: 1 : 6 function_ref = single) (argument_list (argument (declref_expr type = 'String' location = re.swift: 19 : 24 range = [re.swift: 19 : 24 - line: 19 : 24 ] decl = re.( file ).top - level code.data@re.swift: 17 : 9 function_ref = unapplied)) (argument (declref_expr type = 'String' location = re.swift: 19 : 30 range = [re.swift: 19 : 30 - line: 19 : 30 ] decl = re.( file ).top - level code.key@re.swift: 18 : 9 function_ref = unapplied)) )) Processed init: (call_expr type = 'Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 33 ] nothrow (declref_expr type = '(String, String) -> Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 18 ] decl = re.( file ).check@re.swift: 1 : 6 function_ref = single) (argument_list (argument (declref_expr type = 'String' location = re.swift: 19 : 24 range = [re.swift: 19 : 24 - line: 19 : 24 ] decl = re.( file ).top - level code.data@re.swift: 17 : 9 function_ref = unapplied)) (argument (declref_expr type = 'String' location = re.swift: 19 : 30 range = [re.swift: 19 : 30 - line: 19 : 30 ] decl = re.( file ).top - level code.key@re.swift: 18 : 9 function_ref = unapplied)) ))) (var_decl range = [re.swift: 19 : 9 - line: 19 : 9 ] "result" type = 'Bool' interface type = 'Bool' access = fileprivate let readImpl = stored immutable) |
result变量就在call语句块的上方,可以分析出result是初始化的变量,用来初始化result变量的是一个call语句,调用的函数是check,参数分别是data和key
1 | var result = check(data, key) |
1 2 3 4 5 6 7 8 | (pattern_binding_decl range = [re.swift: 18 : 5 - line: 18 : 15 ] (pattern_named type = 'String' 'key' ) Original init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * ) Processed init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * )) (var_decl range = [re.swift: 18 : 9 - line: 18 : 9 ] "key" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
再往上可以找到key的定义
1 | var key = "345y" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (pattern_binding_decl range = [re.swift: 17 : 5 - line: 17 : 39 ] (pattern_named type = 'String' 'data' ) Original init: (subscript_expr type = '<null>' (member_ref_expr type = '@lvalue [String]' location = re.swift: 17 : 28 range = [re.swift: 17 : 16 - line: 17 : 28 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 16 ] typerepr = 'CommandLine' )) (argument_list (argument (integer_literal_expr type = 'Int' location = re.swift: 17 : 38 range = [re.swift: 17 : 38 - line: 17 : 38 ] value = 1 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )) Processed init: (load_expr implicit type = 'String' location = re.swift: 17 : 37 range = [re.swift: 17 : 16 - line: 17 : 39 ] (subscript_expr type = '@lvalue String' location = re.swift: 17 : 37 range = [re.swift: 17 : 16 - line: 17 : 39 ] decl = Swift.( file ).Array extension.subscript(_:) [with (substitution_map generic_signature = <Element> (substitution Element - > String))] (inout_expr implicit type = 'inout Array<String>' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 28 ] (member_ref_expr type = '@lvalue [String]' location = re.swift: 17 : 28 range = [re.swift: 17 : 16 - line: 17 : 28 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 16 ] typerepr = 'CommandLine' ))) (argument_list (argument (integer_literal_expr type = 'Int' location = re.swift: 17 : 38 range = [re.swift: 17 : 38 - line: 17 : 38 ] value = 1 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )))) (var_decl range = [re.swift: 17 : 9 - line: 17 : 9 ] "data" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
这里是data的定义,data是有一个subscript_expr语句块定义的,subscript_expr其实是在去数组的下标,这里取的是arguments[1],也就是第二个命令行参数
1 | var data = CommandLine.arguments[ 1 ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (if_stmt range = [re.swift: 16 : 1 - line: 21 : 1 ] (binary_expr type = 'Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 4 - line: 16 : 35 ] nothrow (dot_syntax_call_expr implicit type = '(Int, Int) -> Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] decl = Swift.( file ). Int extension.> = function_ref = single) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] typerepr = 'Int' )) )) (argument_list implicit (argument (member_ref_expr type = 'Int' location = re.swift: 16 : 26 range = [re.swift: 16 : 4 - line: 16 : 26 ] decl = Swift.( file ).Array extension.count [with (substitution_map generic_signature = <Element> (substitution Element - > String))] (load_expr implicit type = '[String]' location = re.swift: 16 : 16 range = [re.swift: 16 : 4 - line: 16 : 16 ] (member_ref_expr type = '@lvalue [String]' location = re.swift: 16 : 16 range = [re.swift: 16 : 4 - line: 16 : 16 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 16 : 4 range = [re.swift: 16 : 4 - line: 16 : 4 ] typerepr = 'CommandLine' ))))) (argument (integer_literal_expr type = 'Int' location = re.swift: 16 : 35 range = [re.swift: 16 : 35 - line: 16 : 35 ] value = 2 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )) |
在往上是一个if语句,操作符是 >=(extension.>=),操作数一个是argument.count(),一个是2,所以这一块的意思就是比较命令行参数是否大于等于2
1 2 3 | if CommandLine.arguments.count > = 2 { } |
在往上就是top_level_code_decl,顶层表达式了,如图所示,这个程序真是由一个func_decl和一个top_level_code_decl组成,我们已经分析完了下面的top_level_code_decl:
1 2 3 4 5 6 7 8 9 10 | func check(encoded: String, keyValue:String) - > Bool { } if CommandLine.arguments.count > = 2 { let data = CommandLine.arguments[ 1 ] let key = "345y" let result = check(encoded: data, keyValue: key) print (result) } |
1 2 3 4 5 6 7 8 | (func_decl range = [re.swift: 1 : 1 - line: 14 : 1 ] "check(_:_:)" interface type = '(String, String) -> Bool' access = internal (parameter_list range = [re.swift: 1 : 11 - line: 1 : 49 ] (parameter "encoded" type = 'String' interface type = 'String' ) (parameter "keyValue" type = 'String' interface type = 'String' )) (result (type_ident (component id = 'Bool' bind = Swift.( file ). Bool ))) (brace_stmt range = [re.swift: 1 : 59 - line: 14 : 1 ] |
上方函数的大体结构为:参数,返回值和一个表达式
1 2 3 | (parameter_list range = [re.swift: 1 : 11 - line: 1 : 49 ] (parameter "encoded" type = 'String' interface type = 'String' ) (parameter "keyValue" type = 'String' interface type = 'String' )) |
参数分别为encoded和keyValue,都是String类型
1 2 3 | (result (type_ident (component id = 'Bool' bind = Swift.( file ). Bool ))) |
返回值为Bool类型
1 2 3 4 5 6 7 8 9 10 11 12 | (brace_stmt range = [re.swift: 1 : 59 - line: 14 : 1 ] (pattern_binding_decl range = [re.swift: 2 : 5 - line: 2 : 33 ] (var_decl range = [re.swift: 2 : 9 - line: 2 : 9 ] "b" type = '[UInt8]' interface type = '[UInt8]' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (pattern_binding_decl range = [re.swift: 3 : 5 - line: 3 : 34 ] (var_decl range = [re.swift: 3 : 9 - line: 3 : 9 ] "k" type = '[UInt8]' interface type = '[UInt8]' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (pattern_binding_decl range = [re.swift: 4 : 5 - line: 4 : 25 ] (var_decl range = [re.swift: 4 : 9 - line: 4 : 9 ] "r0" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 13 - line: 4 : 13 ] "r1" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 17 - line: 4 : 17 ] "r2" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 21 - line: 4 : 21 ] "r3" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (for_each_stmt range = [re.swift: 5 : 5 - line: 12 : 5 ] (return_stmt range = [re.swift: 13 : 5 - line: 13 : 198 ] |
下方的语句块中又包含了3个定义变量的语句,1个for循环,1个返回语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (pattern_binding_decl range = [re.swift: 2 : 5 - line: 2 : 33 ] (pattern_named type = '[UInt8]' 'b' ) Original init: (call_expr type = '[UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 33 ] nothrow (constructor_ref_call_expr type = '(String.UTF8View) -> [UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 19 ] nothrow (declref_expr implicit type = '(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location = re.swift: 2 : 19 range = [re.swift: 2 : 19 - line: 2 : 19 ] decl = Swift.( file ).Array extension.init(_:) [with (substitution_map generic_signature = <Element, S where Element = = S.Element, S : Sequence> (substitution Element - > UInt8) (substitution S - > String.UTF8View))] function_ref = single) (argument_list implicit (argument (type_expr type = '[UInt8].Type' location = re.swift: 2 : 13 range = [re.swift: 2 : 13 - line: 2 : 19 ] typerepr = '[UInt8]' )) )) (argument_list (argument (member_ref_expr type = 'String.UTF8View' location = re.swift: 2 : 29 range = [re.swift: 2 : 21 - line: 2 : 29 ] decl = Swift.( file ).String extension.utf8 (declref_expr type = 'String' location = re.swift: 2 : 21 range = [re.swift: 2 : 21 - line: 2 : 21 ] decl = re.( file ).check(_:_:).encoded@re.swift: 1 : 14 function_ref = unapplied))) )) Processed init: (call_expr type = '[UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 33 ] nothrow |
第一个定义变量的语句,变量名为b,类型是一个[UInt8]数组,这个数组是由ebcoded(decl=re.(file).check(::).encoded@re.swift)转换过来的
1 | var b = [UInt8](encoded.utf8) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (pattern_binding_decl range = [re.swift: 3 : 5 - line: 3 : 34 ] (pattern_named type = '[UInt8]' 'k' ) Original init: (call_expr type = '[UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 34 ] nothrow (constructor_ref_call_expr type = '(String.UTF8View) -> [UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 19 ] nothrow (declref_expr implicit type = '(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location = re.swift: 3 : 19 range = [re.swift: 3 : 19 - line: 3 : 19 ] decl = Swift.( file ).Array extension.init(_:) [with (substitution_map generic_signature = <Element, S where Element = = S.Element, S : Sequence> (substitution Element - > UInt8) (substitution S - > String.UTF8View))] function_ref = single) (argument_list implicit (argument (type_expr type = '[UInt8].Type' location = re.swift: 3 : 13 range = [re.swift: 3 : 13 - line: 3 : 19 ] typerepr = '[UInt8]' )) )) (argument_list (argument (member_ref_expr type = 'String.UTF8View' location = re.swift: 3 : 30 range = [re.swift: 3 : 21 - line: 3 : 30 ] decl = Swift.( file ).String extension.utf8 (declref_expr type = 'String' location = re.swift: 3 : 21 range = [re.swift: 3 : 21 - line: 3 : 21 ] decl = re.( file ).check(_:_:).keyValue@re.swift: 1 : 33 function_ref = unapplied))) )) Processed init: (call_expr type = '[UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 34 ] nothrow |
同上,接着定义一个变量k
1 | var k = [UInt8](keyValue.utf8) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | (pattern_binding_decl range = [re.swift: 4 : 5 - line: 4 : 25 ] (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r0' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r1' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r2' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r3' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8)))) (var_decl range = [re.swift: 4 : 9 - line: 4 : 9 ] "r0" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 13 - line: 4 : 13 ] "r1" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 17 - line: 4 : 17 ] "r2" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 21 - line: 4 : 21 ] "r3" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) |
接下来的语句块中定义了四个未初始化的变量r0, r1, r2, r3,类型是UInt8
1 | var r0, r1, r2, r3:UInt8 |
1 2 3 4 5 6 7 | (dot_syntax_call_expr implicit type = '(Int, Int) -> ClosedRange<Int>' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> ClosedRange<Int>' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] decl = Swift.( file ).Comparable extension.... [with (substitution_map generic_signature = <Self where Self : Comparable> (substitution Self - > Int ))] function_ref = double) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] typerepr = 'Int' )) )) (argument_list implicit |
可以看到(decl=Swift.(file).Comparable extension....),说明这是一个for-in循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (argument (integer_literal_expr type = 'Int' location = re.swift: 5 : 14 range = [re.swift: 5 : 14 - line: 5 : 14 ] value = 0 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) (argument (binary_expr type = 'Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 18 - line: 5 : 26 ] nothrow (dot_syntax_call_expr implicit type = '(Int, Int) -> Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] decl = Swift.( file ). Int extension. - function_ref = double) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] typerepr = 'Int' )) )) (argument_list implicit (argument (member_ref_expr type = 'Int' location = re.swift: 5 : 20 range = [re.swift: 5 : 18 - line: 5 : 20 ] decl = Swift.( file ).Array extension.count [with (substitution_map generic_signature = <Element> (substitution Element - > UInt8))] (load_expr implicit type = '[UInt8]' location = re.swift: 5 : 18 range = [re.swift: 5 : 18 - line: 5 : 18 ] (declref_expr type = '@lvalue [UInt8]' location = re.swift: 5 : 18 range = [re.swift: 5 : 18 - line: 5 : 18 ] decl = re.( file ).check(_:_:).b@re.swift: 2 : 9 function_ref = unapplied)))) (argument (integer_literal_expr type = 'Int' location = re.swift: 5 : 26 range = [re.swift: 5 : 26 - line: 5 : 26 ] value = 4 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) ))) |
循环的范围是从0到b.count-4
1 2 3 | for i in 0. ..b.count - 4 { } |
紧跟着的是六条赋值语句
展开发现首尾的赋值语句格式相似,中间四条赋值语句格式相似,所以我们应该只需要仔细分析两种不同格式中的各一种
1 2 3 4 5 6 7 8 | (load_expr implicit type = 'UInt8' location = re.swift: 6 : 30 range = [re.swift: 6 : 29 - line: 6 : 32 ] (subscript_expr type = '@lvalue UInt8' location = re.swift: 6 : 30 range = [re.swift: 6 : 29 - line: 6 : 32 ] decl = Swift.( file ).Array extension.subscript(_:) [with (substitution_map generic_signature = <Element> (substitution Element - > UInt8))] (inout_expr implicit type = 'inout Array<UInt8>' location = re.swift: 6 : 29 range = [re.swift: 6 : 29 - line: 6 : 29 ] (declref_expr type = '@lvalue [UInt8]' location = re.swift: 6 : 29 range = [re.swift: 6 : 29 - line: 6 : 29 ] decl = re.( file ).check(_:_:).b@re.swift: 2 : 9 function_ref = unapplied)) (argument_list (argument (declref_expr type = 'Int' location = re.swift: 6 : 31 range = [re.swift: 6 : 31 - line: 6 : 31 ] decl = re.( file ).check(_:_:).i@re.swift: 5 : 9 function_ref = unapplied)) ))) |
这是第一个赋值语句的结构,做的事情是用b数组的值填充r0到r3
1 | r0, r1, r2, r3 = b[i], b[i + 1 ], b[i + 2 ], b[i + 3 ] |
第二个赋值语句,首先是一个取下标,取的是b[i+0]
接着是一个运算语句块
初步看出是用r2异或一个表达式
该表达式是另一个表达式 & 0xff得到
接着又是加运算
一个是k[0]
一个是r0 >> 4
综上,第二个赋值语句:
1 | b[i + 0 ] = r2 ^ ((k[ 0 ] + (r0 >> 4 )) & 0xff ) |
同理可以分析出接下来的几条赋值语句
1 2 3 4 | b[i + 1 ] = r3 ^ ((k[ 1 ] + (r1 >> 2 )) & 0xff ) b[i + 2 ] = r0 ^ k[ 2 ] b[i + 3 ] = r1 ^ k[ 3 ] k[ 0 ], k[ 1 ], k[ 2 ], k[ 3 ] = k[ 1 ], k[ 2 ], k[ 3 ], k[ 0 ] |
for循环之后就是返回语句
返回语句由一条判断语句组成,操作符是==
第一个参数是b数组
第二个参数是一个给定的数组
[88, 35, 88, 225, 7, 201, 57, 94, 77, 56, 75, 168, 72, 218, 64, 91, 16, 101, 32, 207, 73, 130, 74, 128, 76, 201, 16, 248, 41, 205, 103, 84, 91, 99, 79, 202, 22, 131, 63, 255, 20, 16]
1 | return (b = = [ 88 , 35 , 88 , 225 , 7 , 201 , 57 , 94 , 77 , 56 , 75 , 168 , 72 , 218 , 64 , 91 , 16 , 101 , 32 , 207 , 73 , 130 , 74 , 128 , 76 , 201 , 16 , 248 , 41 , 205 , 103 , 84 , 91 , 99 , 79 , 202 , 22 , 131 , 63 , 255 , 20 , 16 ]) |
re.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | func check(encoded: String, keyValue:String) - > Bool { var b = [UInt8](encoded.utf8) var k = [UInt8](keyValue.utf8) var r0, r1, r2, r3:UInt8 for i in 0. ..b.count - 4 { r0 = b[i] r1 = b[i + 1 ] r2 = b[i + 2 ] r3 = b[i + 3 ] b[i + 0 ] = r2 ^ ((k[ 0 ] + (r0 >> 4 )) & 0xff ) b[i + 1 ] = r3 ^ ((k[ 1 ] + (r1 >> 2 )) & 0xff ) b[i + 2 ] = r0 ^ k[ 2 ] b[i + 3 ] = r1 ^ k[ 3 ] let temp = k[ 0 ] k[ 0 ] = k[ 1 ] k[ 1 ] = k[ 2 ] k[ 2 ] = k[ 3 ] k[ 3 ] = temp } return (b = = [ 88 , 35 , 88 , 225 , 7 , 201 , 57 , 94 , 77 , 56 , 75 , 168 , 72 , 218 , 64 , 91 , 16 , 101 , 32 , 207 , 73 , 130 , 74 , 128 , 76 , 201 , 16 , 248 , 41 , 205 , 103 , 84 , 91 , 99 , 79 , 202 , 22 , 131 , 63 , 255 , 20 , 16 ]) } if CommandLine.arguments.count > = 2 { let data = CommandLine.arguments[ 1 ] let key = "345y" let result = check(encoded: data, keyValue: key) print (result) } |
解题脚本
1 2 3 4 5 6 7 8 9 10 11 | b = [ 88 , 35 , 88 , 225 , 7 , 201 , 57 , 94 , 77 , 56 , 75 , 168 , 72 , 218 , 64 , 91 , 16 , 101 , 32 , 207 , 73 , 130 , 74 , 128 , 76 , 201 , 16 , 248 , 41 , 205 , 103 , 84 , 91 , 99 , 79 , 202 , 22 , 131 , 63 , 255 , 20 , 16 ] k = [ 121 , 51 , 52 , 53 ] / / 换位后的key for i in range ( len (b) - 4 , - 1 , - 1 ): k[ 1 ], k[ 2 ], k[ 3 ], k[ 0 ] = k[ 0 ], k[ 1 ], k[ 2 ], k[ 3 ] r1 = k[ 3 ] ^ b[i + 3 ] r0 = k[ 2 ] ^ b[i + 2 ] r3 = ((k[ 1 ] + (r1 >> 2 )) & 0xff ) ^ b[i + 1 ] r2 = ((k[ 0 ] + (r0 >> 4 )) & 0xff ) ^ b[i] b[i], b[i + 1 ], b[i + 2 ], b[i + 3 ] = r0, r1, r2, r3 for i in b: print ( chr (i), end = '') |