Monday 14 December 2020

Saturday 28 November 2020

视频用 N 倍速看对 fps 的影响

如果播放视频时加速,对 fps 有何影响?如何预测会 dropped 多少 frames?

mpv 确实可以 speed up 后如果仍可以满足 monitor 的 refresh rate Hz 就可以不 drop frames。

不过 165 Hz 要求 gpu+cpu 很高否则也是有问题(不然 multitasking 容易 drop frame)。

而且 144 Hz 或 120 Hz 都能被常见的 24 fps 完整除 (120 Hz 能被 youtube 常见的 30 fps 除)

,只有 165 Hz 怪怪的不能整除 (https://www.svp-team.com/forum/viewtopic.php?pid=63214#p63214)。



做个小实验验证一下:






(纠正: mpv 的新选项用法是 -x=value 和 --y 两种, 不再是上面的 --x=value)

如截图,mpv 播放不同 fps 不同速度的小实验,我 Monitor 59.99 Hz:


[1] 30 fps x 2 倍速 = 60 fps,由于我 Monitor 59.99 Hz,不会 drop 任何 frame, ( ( (30 video fps * 30 秒) / (30 秒 / 2.0 speed) ) - 60 Hz) * (30 秒 / 2.0 speed) = ~0 frame。

[2] 120 fps 普通速,由于 120 超出 Monitor 能力 一倍,30 秒后会 dropped ( ( (120 video fps * 30 秒) / (30 秒 / 1.0 speed) ) - 60 Hz) * (30 秒 / 1.0 speed) = ~1800 frames (即总数的一半)

[3] 60 fps x 2 倍速 = 120 fps,由于 120 超出 Monitor 能力 一倍,30 秒后会 dropped (( (60 video fps * 30 秒) / (30 秒 / 2.0 speed) ) - 60 Hz) * (30 秒 / 2.0 speed) = ~900 frames (即总数的一半)

[4] 60 fps x 1.5 倍速,30 秒后会 dropped ( ( (60*30) / (30 /1.5) ) - 60 ) * (30 /1.5)  = ~600 frames (即总数的三分之一)

预测 dropped 多少 frame 只能大概 ~,因为一: Hz 并非整数。二:时间和速度不担保 round 得精准,也因此我使用 --speed=1.99 而不是 2。 三:其它因素譬如 cpu/gpu/multitasking 可以随机 drop。 四:不清楚囧除非研究 mpv 源码 🌚

至于 YouTube player 我觉得 "Stats for Nerds" 的 frame dropped 信不过 🌚 (https://bugzilla.mozilla.org/show_bug.cgi?id=1578042)。我手机 app 60 Hz play 60 fps x 2 speed 却几乎没有任何 drop。

相关问题: https://video.stackexchange.com/questions/15857/what-happens-to-frames-when-you-speed-up-a-video-clip


Thursday 12 November 2020

MySejahtera bug

MySejahtera 的隐私 bug,可以查看其它店的人流, 甚至更新资料。

有些非 Master branch 而看不到更新资料的页面,能通过 email 得知 `Hi contact_name`(有些填手机号)。

由于 bug 会被滥用,我就不公开方法了。(更新: 已被修复)




MySejahtera 没网络 check-in

 实验:

MySejahtera app 在没网络下,扫描二维码后, 政府还能不能收到该 check-in?
 
实验结果:
 
每次点击 "close" 按钮后的十秒, 都会调用 js 的 checkAndSync() 函数, 检查 checkInQue 数据库表之前有没有失败的请求 queue,有的话就(等多一秒)一个个调用 syncCheckIn() 函数尝试 "/clockin" API 终点请求上传。"Clear storage" 会清除该 queue,"Clear Cache" 则不会。
 
实验总结:
 
请确保点击 "close" 按钮后的十一秒后有网络,才能上传之前没网络的 check-in 给政府。即使你扫描新的二维码, 是不会包括之前没网络所累积的 check-in, 必须点击 "close" 按钮等十一秒。十一秒是开始上传的时间,上传全部需时十一秒以上。










我也花了很长时间在 smali 在 enable remote debugging 函数附近加 Log.d()。

实验目标反而是次要,主要目标是顺便学习 smali, 否则要直接在 smali 加 (或删 if/else) enable remote debugging 有何难度?

加 Log.d 原本并不难,可是 `smali/org/apache/cordova/engine/SystemWebViewEngine.smali` 的 `initWebViewSettings()` 恰好是 `.locals 15`。

纯粹改成 16 而不去考虑改其它东西是不大行的,常遇到 error 却不理解为什么不 work。

着手找了 .locals 15 的 java 代码再加大量的代码,终于了解原理和 .locals 的规则。

我之前读的是这个教程,这个教程没提 .locals 15 和 { vx .. vy} 的情况:

首先, .registers 是真的跟 .locals 一样,比 .locals 纯粹多了函数 params 数目, 所以不需要奢望 .registers 可以做到 .locals 做不到的东西。

然后,v17 (.locals v16 + this p0) 意思是可以使用新的 v16, v16 可以想象为 temporary/virtual-variable(我这么形容的), 不实际存在, 但是想象它存在 非-registers 的地方。

要用 v16?  大于 v15 不能直接使用,但有两种使用方式:
【方法一】 先 move-object/from16 v4, v16 复制去小于 v16 的 v4,然后才用 v4。
【方法二】用 { v7 .. v16} ,能写 v16,前提是那些 registers 必须 v7, v8, v9 .. v16 准备好数值。

这样就完了?很可惜,我开头也以为这么容易, 可是其实要考虑 p。

你改成 .locals 16 后,之前的 p0 怎么办?

本来 p1 -> p0 占用 .locals vMax 倒数的目的就是为了方便加 vN 不会影响到现成的 pN, 可以轻松加 smali,对不?

很可惜,.locals 15 加成  16, smali 这特殊情况下帮不到你,需要手动改代码。

假设只有 this p0, p0 之前是 v15,然后你改成 .locals 16,那么你现在用 v15 是没问题的,p0 就升级成 v16。

So far so good, 很可惜,上面说了,大于 v15 的 registers 都是 temporary/virtual registers, 使用的方法不同。

因此你必须改所有涉及 p0 的代码, 先 move-object 才使用抑或更多工的 { pX .. pY}。

我上面强调 .locals 15 加成  16 是 “特殊情况”,是真的很 “特殊”, 即使你 .locals 21 加成 22 是不会有问题的,因为 .locals 21 + 1 existing 的 p0 并没有更改 “使用方法”(已经是 move/{..}了)。 只有 v15 去 v16 才导致 existing 的 p0 从普通方法 “突变” 成 move/{..} 的方法。

这个问题不出所料,网上也常提起

这还没完,v15 还没考虑 params 的数目。譬如 .locals 12 + params 6, 纯粹改成 .locals 13 也是有问题的。因此还要考虑之前 params 有没有属于 v15 的。可以 15 - .locals 12 = p3 要改。如果 .locals 加 2, 那么 p3 和 p2 得连续改。

如果是小数目的 p0 还好,可是 MySejahtera 的 `initWebViewSettings()` 用了大量的 p0,谁这么得空改完?不是不可能,而是很花时间而已。

最后我检查到 v13 少用到(要不然就是用了不再需要, 可以 override)。所以比较快的方式是只 assign v13, 然后重复用在 Log.d 即可达到我的加 Log.d 小目标。


然后 `<application android:debuggable="true"` 也很好用,改了后,不需要 root 也能通过

`adb exec-out run-as my.gov.onegovappstore.mysejahtera cat /data/user/0/my.gov.onegovappstore.mysejaht
era/databases/__ionicstorage > __ionicstorag
e`

的方式从手机复制数据库到电脑 (现在的 Android 的 run-as 不能直接 cp /sdcard/, 所以才比较折腾)。

其实 `android:debuggable="true"` 也能影响上面 `initWebViewSettings()`  的 `if ApplicationInfo flags == true` 而 enable remote debugging。

Saturday 7 November 2020

Facebook 鏈接對下載質量的影響

用 youtube-dl 和 you-get 下載 4 種視頻鏈接格式:
[1] 'https://www.facebook.com/<username>/videos/123/'
[2] 'https://www.facebook.com/<username>/posts/123'
[3] 'https://www.facebook.com/permalink.php?story_fbid=123&id=123'
[4] 'https://www.facebook.com/watch/?v=123'
[5] 手動下載。

實驗結果:
video detail page 的 'https://www.facebook.com/<username>/videos/123/'  或 /watch/ 或手動才能下載最高清視頻。
其餘兩個不僅僅有時下載不了,而是比較低清。

實驗總結:
選什麼鏈接下載並非 optional, 而是必須選 video detail page 的鏈接才能確保下載最高清視頻。


Thursday 22 October 2020

怎样才能在 Facebook 上传下载最高清的图实验。

Android 上传 4 MiB (4032x3024) 的文件, PXL_20201022_141809183.NIGHT.jpg:
[1] 浏览器能下载 241 KiB (1440x1080) 的 JPEG 图。
[2] Android Facebook app 能下载 114 KiB (1080x810) 的 JPEG 图。


浏览器上传同样的 PXL_20201022_141809183.NIGHT.jpg:

[1] 浏览器能下载 509 KiB (2016x1504) 的 JPEG 图。
[2] Android Facebook app 能下载 109 KiB (1080x806) 的 JPEG 图。


实验总结:
要在 Facebook 下载别人最高清的图,上传和下载都必须用浏览器。下载才用浏览器则次之。下载用 Android Facebook app,甭管上传方式,都是最低清,没区别(Android 或浏览器上传都有比对方微小高的可能)。


其它因素:
[1] 此实验的 app 设置 SD/HD 上传没区别。
[2] 通过图库 app 的 "SHARE TO APPS" -> "News Feed" fb icon 上传,与直接在 fb app news feed 上传,两者没区别。
[3] 此实验 app 设置关闭 Data Saver。
[4] 设置朋友/公开权限不影响各下载方式的清晰度。
[5] Browser 的 Save image as, fullscreen "Save image as", "Download" 没区别。以前没 Download 按钮时, fullscreen 才比较高清所以才考虑这个因素。
[6] 以上的 Browser 只指 desktop www.facebook.com,而 m.facebook.com 的 "View Full Size" 则分别是 326 KiB(浏览器上传) 以及 206 KiB (Android 上传),皆介于 Browser 与 Android Facebook app 下载成绩的中间。
[7] 原图编码是 Baseline, 下载后的编码全是 Progressive, 所以不用担心不同编码影响结果。



顺便吐槽下 Konsole 新设计, 它的 find dialog 以前 (Ubuntu 18) 是下方完整的 panel row。

现在 (Ubuntu 20)  则是悬浮小部分在右上方,掩盖我命令行的后端,只能全屏 + 特地上方留空才能截屏完整高亮的结果囧 🎃

不是神仙没预料要截屏而留空只能重运行, 但不是每个命令都能得到同样的 output + 浪费时间。

还有其它
新设计很有问题,譬如 tab 打叉关闭很容易在换 tab 时误按 (右手用滑鼠与键盘交换的速度已很快,不喜太靠边的两个键 Ctrl+Tab)

, 明明以前 Ctrl+D 或偶尔滑鼠右键菜单关闭就完事不香么?

刚开始以为只是想多了, 可这几天我实实在在曾误关闭了几个需要留着的 output tab

,即使新设计检测有进程还在运行会有对话框都不能避免误关这种没进程但有重要 output 的 tab。

还有 scrollbar 太黑不懂如何调, 尝试各种 theme 设置都没效果。

changelog 都是讲为了更好,确定不是在逗? 🎃

我不介意改,但能不能提供设置让用户选择?

If it ain't broke, don't break it, Konsole!



Tuesday 20 October 2020

bash -c "$pitfall"

If user use bash -c "" will easy to get unexpected result if user just copy-paste working code from existing shell session into bash -c "" (OR extend existing bash -c "") and expect it same. But if user use single quotes(outermost) consistently, then user can get rid a lot of trouble.

So, always use ''
single quotes in outermost(of course you can insert "$var" inner to expand if really need while you aware of this pitfall).

Previously I thought bash -c "" OR '' is just favor of choice(sort of isolate process something) until one day I play around with find/xargs and I wonder why `bash -c "dd2=`echo 5` && echo $dd2"` print nothing and why some commands pattern only run correctly on second time(because second time that "global" "$variable" get initialized from first time).

Note that I'm not talking about export environment thing here. `bash -c ''` is just one of the fundamental every shell user MUST know or you waste your time when debugging commands, and worst, unnoticed hidden bug wait for trigger.


Monday 19 October 2020

Facebook 新设计的 bug

如果群组组员的主页 URL 是没用户名 (譬如 https://www.facebook.com/zuck 格式) 而只有 id (譬如 https://www.facebook.com/profile.php?id=12345 格式)

,那么
群组组员页面的 "View Main Profile" 按钮是 link 去 www.facebook.com 而不是该用户的主页。需要去网址栏删除 groups/<组id>/user/ 再浏览。

如果你只有 id 那么就可以减少 (
当然, 不可能完全避免) 组里 stalker 们 stalk 你主页, 反之如果你是搞宣传的且希望在组里引流去你的 profile, 则劝你放个用户名。

我转换去新设计后早就注意到这个 bug 很久了(很明显好不),只是到现在都没去 fix 囧,
fb 的员工懒到囧 😆



Friday 9 October 2020

万恶的 baidu

百度百度, baiduyunguanjia 协议打开网盘程序可以理解,可是你乱入 text/html (点击html 文件得经过网盘程序) 是计划通想干嘛 🎃 

汝即非 html 浏览器,亦非 html 编辑器,
想干嘛?想干 🎃



v2ex 有人调侃 Linux 版网盘先来个硬盘扫描似乎并非调侃 🌚



【2021 更新】

skype 也有类似的情况, lolr share 你毛, 我不喜欢 share 东西囧



Tuesday 6 October 2020

Google Pixel 4a 超坑人的 alarm bug

我就奇怪做么 alarm ⏰ 常没声音,原来 slider 的 alarm volume bar 要超过一半才等于 clock alarm 的第一个 volume,wth  🥶🥶🥶🤖🎃🥃


Media volume 1/3 的声音就够了,所以 Alarm volume 也跟着调 1/3, 没想到是个大坑:


与上图 slider 相应的 volume, 在 clock app 的设置是 mute 囧:


 

来个全景经典画面, 左(slider 设置)1/3, 右 (clock app 设置) 是 mute, 两者名字都称 "Alarm volume" 囧, 应该坑了不少人, 不说了我迟到了 🌚:



Thursday 6 August 2020

Catch 'Err All - universal command to check any log


之前 MCO fb 群组教人 debug 的时候无意中想到, 如果有一个命令,能收集所有常见的错误关键字来秒 grep 会超级有用。

不管你是 /var/log, 还是 logcat,  还是什么鬼程序的 log, 都能轻易看出错误的地方, 这些错误的地方值得关注为啥会错误, 而不是迷失在大量无意义的正常 log。

即便有些错误对程序来说是正常输出,我个人觉得仍然值得关心干啥会有错误字眼。而且有杀过没放过,看多好过遗漏。错误的 log 不是非常多,花不了太多时间, 而且很多是重复性的源自于同一个程序错误, 只要解决该程序问题就能大量减少该错误信息。

我知道 dmesg 可以分类, 譬如 `dmesg --facility=kern --level=emerg,alert,crit,err`。但是仍然不能说正常 log 没有值得关注的错误信息。而且我目标应付是任何程序的  log (当然不可能完美,有些字眼对某些程序或许重要/不重要而遗漏,这种情况下可以加上 -v 稍微检查是否有遗漏, 或添加排除该程序不重要的字眼)。

然后最近又要 debug log  所以就想完善它。我不熟悉 regex 无法做到 prefix 和 postfix 的 negate。且要不保留 non-match(DEBUG) 又要保留 matched line(bug) 非常困难, 网上现有的答案找了几下,也没有找到我要的答案 (有的提 `?!` 但是没有提 prefix 最重要的 `<`, 更别说提 prefix 和 postfix 有区别),就去 UNIX stackexchange 问了大佬,重新完善了此命令。当然随着时间的推移,接触更多种类的 log,未来可以加更多遗漏的关键字或修改。


命令代码和往后的详情更新,请浏览 https://github.com/limkokhole/Catch-Err-All


你可以看到 (?<! b|dia)log(?![a-z]), 表示我要看到有 log 关键字的 line, 但是又不想包括 blog, dialog,logic, login 这些常见字眼。前面是 `?<!` , 后面是 `?<`, 区别只是前面多了一个 `<`。要添加的时候,先检查现成有没有才修改 (比如我要 exclude "dialog",我找到现成已有 "log", 那就在 "log" 那里 extend, 而不是加新的 `| |` )。

 你可能会问有 "impossible" 为何没有常见的 "not possible", 因为 "not" 已拥有自己的 `| |`。所以不需要重复加 "not possible", "not able", "not found" 之类的 | |, 省很多。想一下,有 `not `的 log  是不是很多都是跟错误(或值得关注)有关系的?就是这么个玩法。block 也是同理,有 lock 了不需要 block。改的时候要小心, 譬如 dump 是包括 core.?dump 的哦。err 可能比较常改, 所以最好分 errno  和  interrupt 出来。

还有一些比较主观的讲究, 比如 disabling, revoking ... 我觉得没那么重要,重要的是 disabled, revoked, 所以我才放 disable 而不是  disabl。还有 pause 不是很重要,毕竟只是暂停,并非如 stop 或 cancel 那么重要。放太多会很 noise  所以要取舍。

最后第二个 `\?` 是黑人问号 ?, 如果问号 ? 在 log 是正常的就要拿掉或修改。此命令主要就是 universal template,不是直接用就完美,但起码有个起点让你稍微修改就搞掂。 

最后则是常见的感叹号 "!", 排除常见的 `[ !` shell 格式和 `<! `html tag 以减少噪音, 不过仍然得保留常用来表达某些事物不等同而出错的 `!=` 符号。

有时你想了解上下文,可以加类似 -C 5 的 grep 选项或最后的 ' 前放多一个 `|` (不需要值) 即可显示全部不过仍然有搜索颜色看。

效果截图:





Saturday 27 June 2020

Longest filename test by various downloaders




[补充]

这影片说的是正常的 3 bytes 情况下,如果是故意放 4 bytes 例如 “𪍑” 字, ss youtube 少 8 个𪍑的 32 bytes (不放 PIN_id 则是 7.75 个的 31 bytes)。

you-get 则是下载错误。


观察 you-get 的代码能明显看出简单的 text[:80] 是错误的。

因为截断后的 80 * 4 bytes = 320 bytes, 仍然远远超过一般文件系统限制的  255 bytes。

此测试虽然前面是模拟 Pin ID 的数字,仍然有 263 bytes ,大于我文件系统的 255 bytes。


没有文字描述的图片没有灵魂,所以最大化的使用文件名放描述是很重要的事情。

视频可以靠播放影片弥补,或许还好(不过 ep 放在最后面可能被截断),可是类似 pinterest 的图片下载器就非常需要足够的文字描述, 否则单独的一张图片没有背景描述真的很没意思。

Friday 12 June 2020

Web VS FFmpeg VS duboku-downloader




注:由于测试涉及到连续剧画面,Malaysia, Vietnam, Thailand, South Korea, Indonesia, United States, Taiwan, Philippines, India 的用户需要其它地区的 VPN 才能观看此测试视频。

mpv player 能 skip broken m3u8 chunk, 但是 mplayer, vlc, windows media player 都有卡住的问题,mplayer (vlc 没问题, 忘了 windows media player) 甚至音频在卡住的情况下继续运行,所以卡完后音频比视频快了十秒。我写的下载器通过 pad(暴力循环 17 次(事实上 16 次就够了,不过 `ValueError` 速度超快,多一个 offset 不碍事)找出需要的 16 bytes 之一, 一旦成功 decrypt 即 break) 以及 remux ts to ts 解决了这一问题。我发现 start time 变成 0 而不是保持损失的视频时间四十多分钟才能在接下来的一次性 remux ts to mp4 变成正确的时间。 remux ts to ts 需要加新 muxer mpegts , 所以得重新编译 ffmpeg_minimal_ts_2_mp4.exe。

至于那个速度测试,与其说是我的快(纯 python 本来就不快), 还不如说是 ffmpeg 做冗余的工作导致慢。此测试已经尽可能让 ffmpeg 发挥默认(或许有隐藏选项可是我不懂,普通用户都不懂, 基本虚设) 最好的效能, 例如第一个 m3u8 是 output .ts 而不是 .mp4 以减少不必要的 remux。至于 python 则并非第一次跑 (第一次跑肯定有点慢, 但是现实中下载都是连续的)。 不过 ffmpeg 也好不到哪里去,不是第一次跑,也直接给 m3u8 链接 (现实中, 手动或扩展找 m3u8 链接都要花时间吧)。更新: 后来才发现先转 .mp4 比先转 .ts syscalls (还没算第二次转换)少, 只是不明白之前的随便测试比较是 .ts 比较快。无论如何, 速度差不了几秒, 不然我也不会用先转 .ts 来测试, 都是慢很多。

List syscalls by `strace -c`, duboku-downloader VS ffmpeg -i .m3u8 -c copy .mp4:




我没学 C 所以看不大懂(我小白 😶),不过先脑洞一下: 由于 FFmpeg 也必须支持 live streaming 的 m3u8 ,所以 FFmpeg 的方式可能没优化下载固定时长的 m3u8。

然后我也写了个 python 脚本分析了一下下载 .ts 速度的变化。只显示超过左边栏的差距能大于一秒的,然后右边则是当下累积的差距。能看出来,重新下载仍然是差距 ~37 秒 (最右下是  -37.6)。 此分析忽略时间格式有问题的 .ts, 包括第一个和最后二个两个,不过有其它数据足够分析了。此分析证明 FFmpeg 还是有快过我的地方,不过明显少于我快过它的地方 (右栏,~23 次我快 VS ~9 次它。 左栏则是 20 VS 12)。而且能重点分析为何第三个的 WW8CBwpZ.ts 快了 FFmpeg 近 4.7 秒, 连续则是近 7 秒。不过单体最快反而是 ffmpeg 的 5.7。



新版本的 duboku-downloader 解决了很多 bug,其中解决了 Windows 使用 ffmpeg 会出现烦人的黑窗口。首先认识了 shell=True完整的 string 可以 work。虽然 ffmpeg path 可以解决,可是 source/dest path 比较多工 (还要考虑盲目 concat 的安全性)。不过后来又发现 Windows 和 Linux 用回 list 没问题 ( Windows 用 ffmpeg full path), 只是 Linux 用 single string 需要加上 cwd=os.path.dirname(os.path.realpath(__file__)) 。也发现 Linux 不用 ffmpeg full path 会运行 sh -c ffmpeg ... 可是竟然没有引号 no wonder 上次失败 ! 再后来把 "ffmpeg_minimal_ts_2_mp4.exe" 嵌入 "独播库下载器.exe", 得改用 sys._MEIPASS 才能知道 pyinstaller 默认的 ffmpeg path。以前/开头试过 binaries 也不成功,后来才知道 pyinstaller .sepc 的很多东西要用 tuple 表达, 例如:  binaries=[ ('duboku_lib\\ffmpeg_minimal_ts_2_mp4.exe', 'duboku_lib') ],前者是 pyinstaller 找 ffmpeg_minimal_ts_2_mp4.exe 拿来 build 的路径, 后者则是 runtime 的路径 (也就是 sys._MEIPASS 的子目录)。用在 subprocess 的完整路径就需要 os.path.join(sys._MEIPASS, os.path.join('duboku_lib', ffmpeg_path) )。

项目链接: https://github.com/limkokhole/duboku-downloader

Thursday 14 May 2020

肉眼解析 QR code 的 "a"

 最近读了这篇科普文后,初学尝试用肉眼解析出简单 QR code 的 "a"。

先去这个网站输入 a,生成我们要的简单 QR。




放大:



首先找出版本号,方程式是 (格子边长 - 17) / 4, 因此上图是 (21 格 - 17) / 4 = Version 1。因此版本 2 的边长会多 4 格, 以此类推到 (177 格 - 17) / 4 = 最大的版本 40。对照某些表时,不同版本不同值, 例如 Character Count Indicator 长度, 所以需要版本号。







然后,找用来去掩码的掩模 (Mask pattern),左上寻像图形的正下方 (或左下的正右方) 的第 3-5 格。





三格全黑表示掩模方程式是 j%3 = 0。
解读方程式是从 0, 1, 2 ... 算起,j 是 x轴, i 是 y轴。

EC (Error Correction) Level 则是左上寻像图形 (或左下的正右方) 的第 1-2 格。
两格全黑表示 11 XOR 10(即固定 Mask pattern “10”1010000010010 的左边两个 bits) = 01, 即纠错能力(仅7%)最差的 L 级。因此一眼可见: 黑黑 L(7% 👎), 黑白 M(15%), 白黑 Q(25%), 白白 H(30% 👍)。这篇文我们不理这个。



把掩模从左上往右下盖着,黑格 1, 白格 0, XOR (即不一样才放黑, 1), 最右边形成 (从下往上读。由于掩模右两格都是白色, XOR 后仍然一样,  所以原图不需要改。):

寻像图形 (Finder/Position pattern/marker)
全白
格式信息 (format information)
1 0 结束, 0000 0001, 表示 Data 长度只有 1 个字节。
0 0
0 0
0 0 开始 ECI Character count indicator。由于是 Version 1 且之前的 8-bit Byte Mode, 因此接着只有 8-bit。


0 0 结束,0100,对照 Mode indicators 表,0100 表示 8-bit Byte Mode。


1 0 开始 Mode indicator。
0 1 结束, 0001 1010, 表示 16+8+2=26, 对表 (或这个)即是 ISO/IEC 10646 UTF-8 编码。











0 1
1 0
0 0 开始 ECI 编码。
1 1 继续 -> 右上(1) -> 左上(1), 0111 表示 Mode Indicator 是 ECI。
1 0 开始。顺序: 右下(0) -> 左下(1)。每一行都是从右往左开始读, 不存在左往右。

扫 corner 转去左边的两 bits (从上往下读。掩模这里的两格是白黑, 所以左边不需要改, 只需想像左边纵的黑格是 1,想像右边纵的白格是 1 ):

寻像图形
全白
格式信息 (format information)
1 0 开始 Data, 01 开头属于 0bbb bbbb 的 1 个 codeword(8-bits)。


0 1
0 0
1 0 结束,0110 0001,表示 64+32+1=97,即 ASCII 的 “a”, 找到我们此次的目标。
0 0 由于剩下大于 4 够位, 所以继续 “结束符“。
0 0 结束,4 bit terminator 0000。
0 0 由于 so far 累积的总数是 36-bits ,36 (或最后的 codeword 仅是 4) 不是 8 的倍数, 所以加多 4 个 0 变成 40-bits。
0 0 结束,0000。
1 1
0 1
1 1
0 0

参考:

Wednesday 6 May 2020

Facebook - How to know who unfriend you long long time ago



Note:
If someone block you after unfriend, it still possible to see post by create new account which only added you, so there are still some possibility it will shows post of friend of you.

There are actually 2 privacy bugs here.

First bug is the search able to store deleted comment in plugins( and probably also apply to other places I don't noticed). The first bug shows the over powerful of search by post leads bug.

The second bug take further step of first bug which tick on filter by "Your Friends". This bug proved that the friend relationship never drop even after unfriend, which actually also happen if the new account add only you and unfriend you then the friend suggestion more likely is still your friends.

Monday 13 April 2020

strace vs netstat

A look on the relationship between strace and netstat to diagnose network traffic.



I trying to download blog at https://linux-audit.com/ via python, but `requests.get()` keep stuck until timeout specified, but it able to get response data after timeout.

But curl is working, why?

After dig into strace socket/connect syscalls, I eventually realized that syscalls showing two critical familly, INET and INET6 which represents ipv4 and ipv6 respectively. But INET only run after INET6/timeout.

And I also noticed curl calls both syscalls at sequence without blocking, so it seems at least one is success is fine.

So the solution is monkey-patching the python code to ignore ipv6(or ipv4 if ipv4 not working next time), either https://stackoverflow.com/a/50044152/1074998 or https://stackoverflow.com/a/43950235/1074998 are works.

Anyway, I subscribed mobile network and it changed to ipv6 now, so I can't reproduce anymore ipv4 not working to call ipv6 address at the time of writing.

p/s:  net-tools has been unmaintained for years, and so netstat was deprecated, and you should use `ss` as replacement . --inet/inet6 need replaced by -f inet/inet6 or simply -4/6, but I noticed can't use both -4/-6 same time except not put family options at all. Also need -H do not always shows header which can different width/position and creates unnecessary diff.  And you might want `| column -t` piped from ss.

ss useful to include udp/icmp's ping traffic listed with ip which can't be done in netstat. But still the output columns too messy/wide to see in a glance.





Wednesday 5 February 2020

火狐 - 关闭窗口的警告对话框

现在如果重启火狐后且开启 restore tabs 的功能,则关闭窗口不会有警告对话框。

我不懂别人,但是我开电脑大多数时间都是一直开着火狐的,除非关电脑才关火狐。

换句话说,我很少需要去按火狐的关窗口按钮,因此按关窗口按钮多数都是误触 (或 Ctrl+W 误按到 Ctrl+Q, 抑或误以为 printer preview 是新窗口从而按到 'x' 而不是 Close 按钮囧我每次都..) 。

如果没有警告,就常常发生需要重载 tabs,除了浪费时间,也可能找不回正在看着的东西 (例如更新页面就变化的广告或 Facebook news feed)。

所以启动警告对话框是必须的。

要更改设置可以输入浏览 about:config ,点击 "Accept the Risk and continue", 然后搜索 "onquit" 找到:



然后把 "browser.sessionstore.warnOnQuit""browser.warnOnQuit" , 点击 false 改成 true

要改两个哦,只改其中一个无效。火狐这 combo 操作是哪个天才想出来的。

至于 "browser.tabs.warnOnClose" 则不需要改。

改了后,尝试关闭窗口,不需要重启就能看到效果:



"sessionstore.warnOnQuit" 这个名似乎是 2019 年新增的,一旦本文失效后,得请读者自行再搜了。




Thursday 30 January 2020

Celcom - bypass 无限上网的 tethering 限制

刚要用下 visual studio, 可是电脑似乎是空的,需要下载 visual studio 2019。

需要下载 ~6 GB (其实是安装才 ~6 GB,其实是 ~2 GB 而已, 给它吓尿一下), 不过没有我周额只剩 30% 不到,手机 prepaid 钱只剩下 RM 10.40, 如果再买 2GB 都花光了无法再  renew 平时用的,得出街再进钱。无论如何当时主要原因是给下载 ~6 GB 吓尿。

celcom 有 RM2 unlimited 3 hours 的不过已注明无法 tethering。

然后随便搜下发现 celcom 有 offer 无限上网一小时, 去年 10 月 2 号到 2 月 8 号, 知道太晚了:





虽然没注明不能 tethering , 反而 Internet Pass 说可以 tethering,可是发现 redeem 后也是不能 tethering:



手机终究在自己手中,理论上可以 bypass,可是无限上网只剩下不到一小时,不可能临时研究,就打算放弃了。然后 google 看下别人吹水不爽 celcom 不给 tethering,搜了下 bypass tethering block 找到这个 thread,提到 PdaNet+,就去 play store 下载 PdaNet+:



可是打开 app 它说需要 tethering 的电脑下载 client, 可是无限上网期间 tethering 已 disable 怎样下载囧?:




幸好那个网可以直接手机下载 exe, 然后我那台电脑一时找不到 adb,就直接用 file explorer 打开,然后去 Download 目录即可 cut exe 去电脑打开安装:





安装之前先确保手机 PDANet+ app 除了打勾 "USB Tether" ,如没错也必须打勾 "Hide Tether Usage", 才能实现不让厂商 (Carriers) 侦测到:


然后真的立马可以上网, 且下载 Visual Studio 速度达到几 MB。

好景不常,celcom 似乎早有准备,速度不久就 drop 去几百 KB, 最后甚至几十 KB,re-plug/re-connect 也没用。

只剩半小时不到,我从开发者的角度觉得可能 celcom 侦测手机是否上网才 drop 大量下载的线, 就试了下 chrome/facebook,不行。第二次要放弃的时候,再试 google play store app, 神奇的一幕发生了,速度立马回升到几 MB!

然后很快又掉回去了,我不停的重复刷  app 页下面的 "You might also like" 以及 "Recommended for you" app (即: app 主页 -> scroll 下面 -> 随便点击一个 app -> 重复),才能保持速度在几 MB,真是搞笑。

刷  comment 也能,不过似乎到一个点无效了。所以刷 app 是最好的方法。

最后终于顺利下载完 Visual Studio 了,半小时还未完呢。





网上有人提 UA,不过我的情况不知如何改 UA。而且我开头在 PDANet+ 速度 drop 的时候用手机 chrome 也是一起变慢。

【更新】


要完全避免被侦测需要考虑更多事情