1.JavaScript奇技淫巧:隐形字符
2.关于Majiro引擎的汉化记录
3.原来 JS 的 Array.sort 是插入排序和快速排序的集合!
4.å¨Javascriptä¸ç¾åå·ä»£è¡¨ä»ä¹
JavaScript奇技淫巧:隐形字符
分享一种奇特的JS编程技巧,能实现字符串隐形、不可见。
如下图,操作后字符串长度字节,源码上传不全但内容全不可见。
技术广泛应用于代码加密、数据加密、文字隐藏、内容保密、隐形水印等领域。
隐形效果通过“零宽字符”实现。在Unicode编码中,这些字符不可见、不可打印,调整字符显示格式。
常见的零宽字符有:空格符(U+B)、非断空格符(U+FEFF)、连字符(U+D)、断字符(U+C)、合并收款码源码左至右符(U+E)、右至左符(U+F)。
隐形字符串通过转二进制、替换字符、添加零宽度非断空格符完成,形成全不可见字符串。
隐形字符串还原通过逆操作:将隐形Unicode编码转换为二进制,再转回原字符。
具体源码如下,用于ajax通信时隐秘传递内容。
但存在安全问题,他人可能查看源码,泄露加密方法。需使用JS代码混淆加密提升安全性。
使用JShaman对解密函数进行代码混淆加密,如下图所示。
混淆加密后,代码结构混乱,难以看出功能逻辑。
注意,启动倍量源码“隐形字符”技术适用前后端环境,适用于Node.JS和浏览器。
关于Majiro引擎的汉化记录
在处理Majiro引擎相关工作时,遇到的挑战在于它的工具较为分散且历史久远,主要采用OCaml编写。对于使用GBK编码文本导入的需求,我成功修改了源码并记录了流程,以供有需要的开发者参考,避免走不必要的弯路。
为了使Majiro引擎程序本体能够正常播放语音,需要对部分关键代码进行修改。因为程序通常基于日文字符来判断语音播放,当导入GBK文本时,字符对应的十六进制编码发生改变。通过使用OllyDbg工具直接打开主程序并搜索特定代码片段,将`push 0x`改为`push 0xa1b8`即可。这一步操作需进行2-3次,具体位置可能稍有不同,建议在OllyDbg中定位后,使用Winhex进行修改。delphi指定文件 源码推荐使用wxMEdit编辑器,它支持Unicode家族、SJIS和GBK等常见编码,方便直接浏览二进制文件内容。
对于Majiro引擎的ARC封包处理,使用`arc_conv`工具可以实现有效转换。Majo对象文件(mjo)在解密状态下有其特定的文件头,如`MajiroObjV1.`表示解密版本,`MajiroObjX1.`则为加密版本。解密版本的mjo文件更易于操作,使用wxMEdit查看时,原版文件需使用SJIS编码才能正确显示字符串内容。
在讨论Majiro引擎的汉化工作时,通常涉及到`mjasm`和`mjdisasm`两个重要工具。通过使用`mjdisasm`,可以将mjo脚本拆分为mjs和sjs文件,其中mjs文件包含脚本逻辑,sjs文件包含字符串。而`mjasm`则可以将修改后的mjs和sjs文件组合成新的mjo文件。由于原版mjo文件采用SJIS编码,易语言 源码下载无法直接用于汉化工作,因此作者选择了重新编译支持GBK编码导入的版本。
Mjdev工具作为Majiro引擎的重要组成部分,提供了编译好的版本,包含了一系列组件。汉化工作主要依赖于`mjasm`和`mjdisasm`两个工具,它们分别用于处理mjs和sjs文件的编码转换。要实现汉化,作者自行编译了一个支持GBK编码导入的Mjdev版本,通过配置相应的环境依赖,包括OCaml、ExtLib库以及bash环境,最终实现了对Majiro引擎的适应性增强。
针对操作系统环境的优化,作者推荐使用Windows的Ubuntu子系统,替代传统的cygwin环境,以简化配置过程。通过安装Ubuntu子系统并创建普通用户,可以更方便地使用opam等工具来管理OCaml环境。在完成环境配置后,使用opam创建OCaml 3..0的编译环境,并通过下载、编译和安装ExtLib库,实现了Mjdev工具的自定义编译。
为了解决Mjdev中的一些兼容性问题,如对于GBK编码的支持以及特定opcode和指令格式的处理,作者对源代码进行了针对性的修改。具体来说,修改了判断有效字符范围的代码,更新了mjs文件的处理逻辑,以及调整了mjo文件的读取规则,以适应GBK编码的文本。这些修改不仅提升了工具的兼容性,也使得Majiro引擎在处理非日文编码的文本时更加灵活。
最后,作者提供了其编译的Mjdev版本的下载链接,以供有需要的开发者使用。链接中包含了针对GBK编码优化的版本,需要在bash环境下执行。针对原版代码中存在的指令生成顺序问题,作者已进行了修正,以避免不必要的调试工作。
原来 JS 的 Array.sort 是插入排序和快速排序的集合!
深入解析 JS 数组的 `sort` 方法,你将发现它是快速排序和插入排序的巧妙结合。这篇文章带你探索 `sort` 方法的内部实现,了解它如何根据数组的长度选择合适的排序算法,从而提升编程思维。
`sort` 方法的基本使用涉及到对数组元素进行排序,返回的是排序后的数组引用。默认情况下,数组元素会被转换为字符串,然后按照 UTF- 码元值进行升序排序。此排序行为依赖于具体实现,因此其时间和空间复杂度无法保证。
为了自定义排序顺序,可以提供一个 `compareFunction` 函数,用于比较两个元素,并返回一个数字,正负性表示两个元素的相对顺序。这个函数使用一系列参数调用,确保排序过程符合预期。
若未提供 `compareFunction`,所有非 `undefined` 的数组元素将转换为字符串进行排序。数值排序时,9 在 之前排序,但在 Unicode 顺序中,“”排在“9”之前。所有 `undefined` 元素会被排列到数组末尾。
接下来,让我们探索 `sort` 方法的底层实现。在 V8 内部,`sort` 方法对于多种边界情况进行了优化,其源码揭示了有趣实现。对于数组长度 n 的不同情况,`sort` 方法采用了不同的排序算法。
当 n 小于等于 时,插入排序被采用;插入排序是一种直观简单的排序算法,通过构建有序序列,扫描未排序数据,找到相应位置并插入,实现排序效果。插入排序在小数据集上性能优越,尤其是在数据量足够小时,其性能优于快速排序或合并排序。
当 n 大于 时,快速排序成为首选。快速排序的基本思想是通过一趟排序将待排记录分隔成独立两部分,其中一部分记录的关键字均比另一部分的小,递归地对这两部分进行排序。快速排序的核心是“三路切分”,通过一个整数 x 将数组切分成小于、等于、大于三部分,实现时间复杂度 O(N),空间复杂度 O(1)。
具体来说,当 n 小于 时,直接取中点作为三路切分的中位数。当 n 大于 时,通过挑选元素排序后取中位数。这样的设计旨在优化排序性能,避免在某些极端情况下退化为 O(n^2) 级别的时间复杂度。
总之,`sort` 方法结合了快速排序和插入排序,根据数组长度选择最优排序算法。当数据量较小(n 小于等于 )时,插入排序性能更优;当数据量较大时,快速排序的性能优势显著。深入理解 `sort` 方法的实现逻辑,有助于提升 JavaScript 编程能力,增强对算法的理解。
å¨Javascriptä¸ç¾åå·ä»£è¡¨ä»ä¹
%XX表示ä¸ä¸ªASCII代ç 为XXçå符ãå¦ %3C表示<ï¼%3D表示=ï¼%è¡¨ç¤ºç©ºæ ¼çã
ç¨escapeä¸unescapeå¯ä»¥ç¼ç æ解ç ã
é常ï¼è¿ä¸ªè¢«ç¨äºè¡¨ç¤ºä¸äºç¹æ®å符ï¼æè ç¨äºç®åå å¯ã
ç±äºJavascript代ç åµå ¥å¨HTMLä¸ï¼è½è¢«å«äººæ¥çæºä»£ç çæ¹å¼çå°ï¼æ以éè¿è¿ç§æ¹å¼å å¯ï¼åªæ¯çæºä»£ç ä¸æ¶è¿ä¸ç¥ééé¢ç©¶ç«æ¯ä»ä¹ã
ä¾å¦ä½ çç¨åºä¸ï¼å®é ä¸çHTML代ç æ¯è¿ä¸²å符ï¼
<p align="center"><iframe name="weather_inc" src="/cframe?type="6" width="" height="" frameborder="0" marginwidth="0" marginheight="0" scrolling="no">...
ä¸è¿ç»è¿å å¯åå°±çä¸æ¸ å¦ã
å®é ä¸è¿ä¸ªé²ååä¸é²å°äººï¼ä¼ç¼ç¨çç®åå¤çä¸ä¸å°±çå°äºã