base64魔改算法 | jsvmp日志分析并还原

前言

上一篇我们讲了标准 base64 算法还原,为了进一步学习 base64 算法特点,本文将结合 jsvmp 日志,实战还原出 base64 魔改算法。

为了方便大家学习,我将入参和上篇文章一样,入参为 Hello, World!。

插桩

在js代码中,找到 运算符 位置以及 apply 插桩点,结合插桩日志框架,代码插桩如下:

jsvmp源码:https://t.zsxq.com/B5aRh

base64魔改算法 | jsvmp日志分析并还原

日志分析

代码执行后,日志如下:

第 1 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 0 ] 结果: 72
第 2 条:  函数: [Function: push] 调用者: [ 72 ] 参数: [ 72 ] 结果: 1
第 3 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 1 ] 结果: 101
第 4 条:  函数: [Function: push] 调用者: [ 72, 101 ] 参数: [ 101 ] 结果: 2
第 5 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 2 ] 结果: 108
第 6 条:  函数: [Function: push] 调用者: [ 72, 101, 108 ] 参数: [ 108 ] 结果: 3
第 7 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 3 ] 结果: 108
第 8 条:  函数: [Function: push] 调用者: [ 72, 101, 108, 108 ] 参数: [ 108 ] 结果: 4
第 9 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 4 ] 结果: 111
第 10 条:  函数: [Function: push] 调用者: [ 72, 101, 108, 108, 111 ] 参数: [ 111 ] 结果: 5
第 11 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 5 ] 结果: 44
第 12 条:  函数: [Function: push] 调用者: [ 72, 101, 108, 108, 111, 44 ] 参数: [ 44 ] 结果: 6
第 13 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 6 ] 结果: 32
第 14 条:  函数: [Function: push] 调用者: [72, 101, 108, 108,111,  44,  32
] 参数: [ 32 ] 结果: 7
第 15 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 7 ] 结果: 87
第 16 条:  函数: [Function: push] 调用者: [72, 101, 108, 108,111,  44,  32,  87
] 参数: [ 87 ] 结果: 8
第 17 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 8 ] 结果: 111
第 18 条:  函数: [Function: push] 调用者: [72, 101, 108, 108,111,  44,  32,  87,111
] 参数: [ 111 ] 结果: 9
第 19 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 9 ] 结果: 114
第 20 条:  函数: [Function: push] 调用者: [72, 101, 108, 108,111,  44,  32,  87,111, 114
] 参数: [ 114 ] 结果: 10
第 21 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 10 ] 结果: 108
第 22 条:  函数: [Function: push] 调用者: [72, 101, 108, 108,111,  44,  32,  87,111, 114, 108
] 参数: [ 108 ] 结果: 11
第 23 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 11 ] 结果: 100
第 24 条:  函数: [Function: push] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100
] 参数: [ 100 ] 结果: 12
第 25 条:  函数: [Function: charCodeAt] 调用者: Hello, World! 参数: [ 12 ] 结果: 33
第 26 条:  函数: [Function: push] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 33 ] 结果: 13
第 27 条:  0 + 3 ====> 3
第 28 条:  函数: [Function: slice] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 0, 3 ] 结果: [ 72, 101, 108 ]
第 29 条:  函数: [Function: slice] 调用者: [ 72, 101, 108 ] 参数: [] 结果: [ 72, 101, 108 ]
第 30 条:  3 - 3 ====> 0
第 31 条:  72 & 255 ====> 72
第 32 条:  101 & 255 ====> 101
第 33 条:  108 & 255 ====> 108
第 34 条:  72 << 16 ====> 4718592
第 35 条:  101 << 8 ====> 25856
第 36 条:  4718592 | 25856 ====> 4744448
第 37 条:  4744448 | 108 ====> 4744556
第 38 条:  4744556 >> 18 ====> 18
第 39 条:  18 & 63 ====> 18
第 40 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 18 ] 结果: w
第 41 条:  4744556 >> 12 ====> 1158
第 42 条:  1158 & 63 ====> 6
第 43 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 6 ] 结果: 4
第 44 条:  4744556 >> 6 ====> 74133
第 45 条:  74133 & 63 ====> 21
第 46 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 21 ] 结果: X
第 47 条:  4744556 & 63 ====> 44
第 48 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 44 ] 结果: u
第 49 条:  函数: [Function: apply] 调用者: [Function: t4] 参数: [ null, [ 72, 101, 108 ] ] 结果: [ 'w', '4', 'X', 'u' ]
第 50 条:   + w ====> w
第 51 条:  w + 4 ====> w4
第 52 条:  w4 + X ====> w4X
第 53 条:  w4X + u ====> w4Xu
第 54 条:  0 + 3 ====> 3
第 55 条:  3 + 3 ====> 6
第 56 条:  函数: [Function: slice] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 3, 6 ] 结果: [ 108, 111, 44 ]
第 57 条:  函数: [Function: slice] 调用者: [ 108, 111, 44 ] 参数: [] 结果: [ 108, 111, 44 ]
第 58 条:  3 - 3 ====> 0
第 59 条:  108 & 255 ====> 108
第 60 条:  111 & 255 ====> 111
第 61 条:  44 & 255 ====> 44
第 62 条:  108 << 16 ====> 7077888
第 63 条:  111 << 8 ====> 28416
第 64 条:  7077888 | 28416 ====> 7106304
第 65 条:  7106304 | 44 ====> 7106348
第 66 条:  7106348 >> 18 ====> 27
第 67 条:  27 & 63 ====> 27
第 68 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 27 ] 结果: +
第 69 条:  7106348 >> 12 ====> 1734
第 70 条:  1734 & 63 ====> 6
第 71 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 6 ] 结果: 4
第 72 条:  7106348 >> 6 ====> 111036
第 73 条:  111036 & 63 ====> 60
第 74 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 60 ] 结果: S
第 75 条:  7106348 & 63 ====> 44
第 76 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 44 ] 结果: u
第 77 条:  函数: [Function: apply] 调用者: [Function: t4] 参数: [ null, [ 108, 111, 44 ] ] 结果: [ '+', '4', 'S', 'u' ]
第 78 条:  w4Xu + + ====> w4Xu+
第 79 条:  w4Xu+ + 4 ====> w4Xu+4
第 80 条:  w4Xu+4 + S ====> w4Xu+4S
第 81 条:  w4Xu+4S + u ====> w4Xu+4Su
第 82 条:  3 + 3 ====> 6
第 83 条:  6 + 3 ====> 9
第 84 条:  函数: [Function: slice] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 6, 9 ] 结果: [ 32, 87, 111 ]
第 85 条:  函数: [Function: slice] 调用者: [ 32, 87, 111 ] 参数: [] 结果: [ 32, 87, 111 ]
第 86 条:  3 - 3 ====> 0
第 87 条:  32 & 255 ====> 32
第 88 条:  87 & 255 ====> 87
第 89 条:  111 & 255 ====> 111
第 90 条:  32 << 16 ====> 2097152
第 91 条:  87 << 8 ====> 22272
第 92 条:  2097152 | 22272 ====> 2119424
第 93 条:  2119424 | 111 ====> 2119535
第 94 条:  2119535 >> 18 ====> 8
第 95 条:  8 & 63 ====> 8
第 96 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 8 ] 结果: K
第 97 条:  2119535 >> 12 ====> 517
第 98 条:  517 & 63 ====> 5
第 99 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 5 ] 结果: h
第 100 条:  2119535 >> 6 ====> 33117
第 101 条:  33117 & 63 ====> 29
第 102 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 29 ] 结果: U
第 103 条:  2119535 & 63 ====> 47
第 104 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 47 ] 结果: F
第 105 条:  函数: [Function: apply] 调用者: [Function: t4] 参数: [ null, [ 32, 87, 111 ] ] 结果: [ 'K', 'h', 'U', 'F' ]
第 106 条:  w4Xu+4Su + K ====> w4Xu+4SuK
第 107 条:  w4Xu+4SuK + h ====> w4Xu+4SuKh
第 108 条:  w4Xu+4SuKh + U ====> w4Xu+4SuKhU
第 109 条:  w4Xu+4SuKhU + F ====> w4Xu+4SuKhUF
第 110 条:  6 + 3 ====> 9
第 111 条:  9 + 3 ====> 12
第 112 条:  函数: [Function: slice] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 9, 12 ] 结果: [ 114, 108, 100 ]
第 113 条:  函数: [Function: slice] 调用者: [ 114, 108, 100 ] 参数: [] 结果: [ 114, 108, 100 ]
第 114 条:  3 - 3 ====> 0
第 115 条:  114 & 255 ====> 114
第 116 条:  108 & 255 ====> 108
第 117 条:  100 & 255 ====> 100
第 118 条:  114 << 16 ====> 7471104
第 119 条:  108 << 8 ====> 27648
第 120 条:  7471104 | 27648 ====> 7498752
第 121 条:  7498752 | 100 ====> 7498852
第 122 条:  7498852 >> 18 ====> 28
第 123 条:  28 & 63 ====> 28
第 124 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 28 ] 结果: W
第 125 条:  7498852 >> 12 ====> 1830
第 126 条:  1830 & 63 ====> 38
第 127 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 38 ] 结果: o
第 128 条:  7498852 >> 6 ====> 117169
第 129 条:  117169 & 63 ====> 49
第 130 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 49 ] 结果: J
第 131 条:  7498852 & 63 ====> 36
第 132 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 36 ] 结果: L
第 133 条:  函数: [Function: apply] 调用者: [Function: t4] 参数: [ null, [ 114, 108, 100 ] ] 结果: [ 'W', 'o', 'J', 'L' ]
第 134 条:  w4Xu+4SuKhUF + W ====> w4Xu+4SuKhUFW
第 135 条:  w4Xu+4SuKhUFW + o ====> w4Xu+4SuKhUFWo
第 136 条:  w4Xu+4SuKhUFWo + J ====> w4Xu+4SuKhUFWoJ
第 137 条:  w4Xu+4SuKhUFWoJ + L ====> w4Xu+4SuKhUFWoJL
第 138 条:  9 + 3 ====> 12
第 139 条:  12 + 3 ====> 15
第 140 条:  函数: [Function: slice] 调用者: [72, 101, 108, 108, 111,44,  32,  87, 111, 114,108, 100,  33
] 参数: [ 12, 15 ] 结果: [ 33 ]
第 141 条:  函数: [Function: slice] 调用者: [ 33 ] 参数: [] 结果: [ 33 ]
第 142 条:  3 - 1 ====> 2
第 143 条:  函数: [Function: push] 调用者: [ 33, 0 ] 参数: [ 0 ] 结果: 2
第 144 条:  3 - 1 ====> 2
第 145 条:  函数: [Function: push] 调用者: [ 33, 0, 0 ] 参数: [ 0 ] 结果: 3
第 146 条:  3 - 1 ====> 2
第 147 条:  33 & 255 ====> 33
第 148 条:  0 & 255 ====> 0
第 149 条:  0 & 255 ====> 0
第 150 条:  33 << 16 ====> 2162688
第 151 条:  0 << 8 ====> 0
第 152 条:  2162688 | 0 ====> 2162688
第 153 条:  2162688 | 0 ====> 2162688
第 154 条:  2162688 >> 18 ====> 8
第 155 条:  8 & 63 ====> 8
第 156 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 8 ] 结果: K
第 157 条:  2162688 >> 12 ====> 528
第 158 条:  528 & 63 ====> 16
第 159 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 16 ] 结果: f
第 160 条:  2162688 >> 6 ====> 33792
第 161 条:  33792 & 63 ====> 0
第 162 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 0 ] 结果: D
第 163 条:  2162688 & 63 ====> 0
第 164 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 0 ] 结果: D
第 165 条:  函数: [Function: apply] 调用者: [Function: t4] 参数: [ null, [ 33, 0, 0 ] ] 结果: [ 'K', 'f', 'D', 'D' ]
第 166 条:  w4Xu+4SuKhUFWoJL + K ====> w4Xu+4SuKhUFWoJLK
第 167 条:  w4Xu+4SuKhUFWoJLK + f ====> w4Xu+4SuKhUFWoJLKf
第 168 条:  w4Xu+4SuKhUFWoJLKf + = ====> w4Xu+4SuKhUFWoJLKf=
第 169 条:  w4Xu+4SuKhUFWoJLKf= + = ====> w4Xu+4SuKhUFWoJLKf==
第 170 条:  12 + 3 ====> 15
第 171 条:  函数: [Function: t4] 调用者: Object [global] {'@faceless': <ref *1> Object [global] {global: [Circular *1],queueMicrotask: [Function: queueMicrotask],clearImmediate: [Function: clearImmediate],setImmediate: [Function: setImmediate] {[Symbol(nodejs.util.promisify.custom)]: [Getter]},structuredClone: [Getter/Setter],clearInterval: [Function: clearInterval],clearTimeout: [Function: clearTimeout],setInterval: [Function: setInterval],setTimeout: [Function: setTimeout] {[Symbol(nodejs.util.promisify.custom)]: [Getter]},atob: [Getter/Setter],btoa: [Getter/Setter],performance: [Getter/Setter],fetch: [AsyncFunction: fetch],window: [Circular *1]},arguments: undefined,optimizedBase64Encode: [Function: t4]
} 参数: [ 'Hello, World!' ] 结果: w4Xu+4SuKhUFWoJLKf==
w4Xu+4SuKhUFWoJLKf==

实战过程中,当看到 w4Xu+4SuKhUFWoJLKf== 这个字符后,看起来像是 base64 编码,所以通过 atob 尝试解码,得到 Ã\x85îû\x84®*\x15\x05Z\x82K),显然不对。

那分析日志吧!

第 29 条:  函数: [Function: slice] 调用者: [ 72, 101, 108 ] 参数: [] 结果: [ 72, 101, 108 ]
第 30 条:  3 - 3 ====> 0
第 31 条:  72 & 255 ====> 72
第 32 条:  101 & 255 ====> 101
第 33 条:  108 & 255 ====> 108
第 34 条:  72 << 16 ====> 4718592
第 35 条:  101 << 8 ====> 25856
第 36 条:  4718592 | 25856 ====> 4744448
第 37 条:  4744448 | 108 ====> 4744556
第 38 条:  4744556 >> 18 ====> 18
第 39 条:  18 & 63 ====> 18
第 40 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 18 ] 结果: w
第 41 条:  4744556 >> 12 ====> 1158
第 42 条:  1158 & 63 ====> 6
第 43 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 6 ] 结果: 4
第 44 条:  4744556 >> 6 ====> 74133
第 45 条:  74133 & 63 ====> 21
第 46 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 21 ] 结果: X
第 47 条:  4744556 & 63 ====> 44
第 48 条:  函数: [Function: charAt] 调用者: Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe= 参数: [ 44 ] 结果: u

看到这段日志,有什么发现吗?

上篇文章讲过,如果是 3 个字节值通过位运算得到一个 4 个字节值,即:72, 101, 108 ===> 18, 6, 21, 44

所以,我们判断,它大概是 标准base64或者变种 base64算法,由于我们验证过,它不是标准base64,所以它应该是变种base64。

那么,既然知道它大概是变种base64,那我们还需要一步一步去日志还原吗?

答案肯定不需要的。

我们只需要拿着 base64标准算法模板去改就行。俗称:套模板,大大节省我们的时间,而且也不容易出错!

标准 base64 算法模版:https://t.zsxq.com/sphu5

首先控制入参一样,即:Hello, World!。

分析日志发现,首先它把标准的 base64 算法,码表由 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 变成了 Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=。

其次是:

第 31 条:  72 & 255 ====> 72
第 32 条:  101 & 255 ====> 101
第 33 条:  108 & 255 ====> 108

每次位运算之前,都进行了 & 255 操作。

所以我们只需要微调代码,如下:

function processGroup(a, b, c) {a = a & 255; // 追加内容b = b & 255; // 追加内容c = c & 255; // 追加内容var combined = (a << 16) | (b << 8) | c;return [base64Chars.charAt((combined >> 18) & 63),base64Chars.charAt((combined >> 12) & 63),base64Chars.charAt((combined >> 6) & 63),base64Chars.charAt(combined & 63)];
}

最后,我们再验证一下,发现结果也是 w4Xu+4SuKhUFWoJLKf==,和日志结果一致,说明我们还原成功!

完整代码:https://t.zsxq.com/ROTc7

下一篇文章我们分析 RC4 jsvmp算法,学习它的日志特点。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/pingmian/90550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3笔记(2)自用

目录 一、作用域插槽 二、pinia的使用 一、Pinia 基本概念与用法 1. 安装与初始化 2. 创建 Store 3. 在组件中使用 Store 4. 高级用法 5、storeToRefs 二、Pinia 与 Vuex 的主要区别 三、为什么选择 Pinia&#xff1f; 三、定义全局指令 1.封装通用 DOM 操作&#…

大模型面试回答,介绍项目

1. 模型准备与转换&#xff08;PC端/服务器&#xff09;你先在PC上下载或训练好大语言模型&#xff08;如HuggingFace格式&#xff09;。用RKLLM-Toolkit把模型转换成瑞芯微NPU能用的专用格式&#xff08;.rkllm&#xff09;&#xff0c;并可选择量化优化。把转换好的模型文件拷…

Oracle 19.20未知BUG导致oraagent进程内存泄漏

故障现象查询操作系统进程的使用排序&#xff0c;这里看到oraagent的物理内存达到16G&#xff0c;远远超过正常环境&#xff08;正常环境在19.20大概就是100M多一点&#xff09;[rootorastd tmp]# ./hmem|more PID NAME VIRT(kB) SHARED(kB) R…

尝试几道算法题,提升python编程思维

一、跳跃游戏题目描述&#xff1a; 给定一个非负整数数组 nums&#xff0c;你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。示例&#xff1a;输入&#xff1a;nums [2,3,1,1,4] → 输出&#xff1a;True输入…

【菜狗处理脏数据】对很多个不同时间序列数据的文件聚类—20250722

目录 具体做法 可视化方法1&#xff1a;PCA降维 可视化方法2、TSNE降维可视化&#xff08;非线性降维&#xff0c;更适合聚类&#xff09; 可视化方法3、轮廓系数评判好坏 每个文件有很多行列的信息&#xff0c;每列是一个驾驶相关的数据&#xff0c;需要对这些文件进行聚类…

Qwen-MT:翻得快,译得巧

我们再向大家介绍一位新朋友&#xff1a;机器翻译模型Qwen-MT。开发者朋友们可通过Qwen API&#xff08;qwen-mt-turbo&#xff09;&#xff0c;来直接体验它又快又准的翻译技能。 本次更新基于强大的 Qwen3 模型&#xff0c;进一步使用超大规模多语言和翻译数据对模型进行训练…

在 OceanBase 中,使用 TO_CHAR 函数 直接转换日期格式,简洁高效的解决方案

SQL语句SELECT TO_CHAR(TO_DATE(your_column, DD-MON-YY), YYYY-MM-DD) AS formatted_date FROM your_table;关键说明&#xff1a;核心函数&#xff1a;TO_DATE(30-三月-15, DD-MON-YY) → 将字符串转为日期类型TO_CHAR(..., YYYY-MM-DD) → 格式化为 2015-03-30处理中文月份&a…

pnpm运行electronic项目报错,npm运行正常。electronic项目打包为exe报错

pnpm运行electronic项目报错 使用 pnpm 运行 electronic 项目报错&#xff0c;npm 运行正常&#xff0c;报错内容如下 error during start dev server and electron app: Error: Electron uninstallat getElectronPath (file:///E:/project/xxx-vue/node_modules/.pnpm/elect…

8️⃣ 高级特性—— 列表生成式

文章目录&#x1f9e0; 总结1. 基本语法2. 加筛选条件&#x1f501; 双层循环&#xff08;全排列&#xff09;&#x1f4c2; 遍历目录&#x1f511; 遍历字典&#x1f521; 转小写3. if 和 if...else 的区别4. 练习题&#x1f9e0; 总结 特性用法示例基础语法[x for x in iter…

DocC的简单使用

DocC的简单使用 在写3GShare中&#xff0c;由于刚开始使用MVC模式来写东西&#xff0c;对很多东西都不是很熟&#xff0c;经常写着写着就忘了自己在写什么&#xff0c;所以学了一下DocC来加快开发进度 什么是DocC 简单来说&#xff0c;DocC就是更高级的注释&#xff0c;虽然…

深入理解C语言快速排序与自省排序(Introsort)

排序算法是计算机科学中最基础也是最重要的知识之一。快速排序&#xff08;Quicksort&#xff09;因其平均时间复杂度为 O(n log n) 而广受欢迎&#xff0c;但在最坏情况下会退化到 O(n)。为了克服这一缺点&#xff0c;自省排序&#xff08;Introsort&#xff09; 应运而生&…

C#编程基础:运算符与结构详解

目录 一.关系运算符 常见关系运算符 二.逻辑运算符 常见逻辑运算符 1. 逻辑与&#xff08;&& 或 and&#xff09; 2. 逻辑或&#xff08;|| 或 or&#xff09; 3. 逻辑非&#xff08;! 或 not&#xff09; 运算符优先级 三.if语句 1.c#程序的三大结构 1.顺序…

嵌入式学习-土堆目标检测(3)-day27

再学一个labelme在labelstudio环境中再pip install labelme安装好后直接输入 labelme之后点击保存&#xff0c;选择保存文件地址还有一个就是将labelme的格式转化为yolo格式还是在labelstudio这个环境里面安装pip install labelme2yolo

Qt OpenGL 集成:开发 3D 图形应用

Qt 提供了完善的 OpenGL 集成方案&#xff0c;使开发者能够在 Qt 应用中高效开发 3D 图形应用。通过 Qt 的 OpenGL 模块&#xff0c;可简化 OpenGL 上下文管理、窗口渲染和跨平台适配&#xff0c;同时结合现代 OpenGL 特性&#xff08;如着色器、顶点缓冲、纹理等&#xff09;实…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 热词评论查询功能实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解热词评论查询功能实现 视频在线地址&#…

使用 Google Earth 的 DEM — 教程。

数字高程模型 (DEM)描绘了已知高程点之间的表面高程。本教程将向您展示如何使用 Google Earth 的高程数据生成 DEM。在当今世界&#xff0c;DEM 主要用于 GIS 应用。 当然&#xff0c;我们可以从美国地质调查局 (USGS) 网站下载数字高程模型 (DEM)。但如果我们想知道某个地点的…

在 UniApp 中实现中间凸起 TabBar 的完整指南

如何在 UniApp 中设置中间 TabBar 凸起效果 在移动应用开发中&#xff0c;TabBar 是常见的导航组件&#xff0c;而中间凸起的 TabBar 按钮则是一种流行的设计风格&#xff0c;常用于突出重要功能&#xff08;如发布、拍照等&#xff09;。UniApp 提供了 midButton 属性&#xf…

微观低代码

今日去深圳的一家工厂给客户做培训&#xff0c;主要培训内容为低代码产品的二开和功能演示。客户使用了20年的ERP和OA系统&#xff0c;目前想对接到低代码平台。客户目前想实现的主要功能是&#xff0c;对接OA的单点登录&#xff0c;把ERP的功能迁移到低代码平台上来工厂规模比…

Linux进程控制:掌握系统的核心脉络

Linux进程控制&#xff1a;掌握系统的核心脉络 在 Linux 系统中&#xff0c;进程控制是系统运行的核心机制之一。无论是日常的命令行操作&#xff0c;还是复杂的后台服务运行&#xff0c;都离不开对进程的管理和控制。本文将深入探讨 Linux 进程控制的相关知识&#xff0c;帮助…

4N90-ASEMI电机控制专用4N90

编辑&#xff1a;LL4N90-ASEMI电机控制专用4N90型号&#xff1a;4N90品牌&#xff1a;ASEMI封装&#xff1a;ITO-220ABRDS(on):3.60Ω批号&#xff1a;最新引脚数量&#xff1a;3封装尺寸&#xff1a;如图特性&#xff1a;N沟道MOS管工作结温&#xff1a;-55℃~150℃一、卓越性…