之前見到類似https://lih.kg/kujgRS 嘅link,見到kujgRS呢啲類似youtube id base64嘅碼,就覺得佢唔係直接server無啦啦生成出一個unique code save低再link返去個頁面同回覆,你會發現撳嘅時候係即時出現,Network唔會出現任何嘢,即係話佢係用local js嚟轉,有佢嘅規則,所以先可以直接出現
後尾我花咗啲時間去研究,終於明白係點嚟,佢lih.kg/ 之後有幾個模式
首先最簡單,後面打數字即係post id,直接去嗰個post第一頁,例如https://lih.kg/3572839
之後有啲複雜
首先,要知道佢係有分大細楷嘅,先講吓其實S開始到Z其實係reserved character嚟,係保留咗嘅,即係STUVWXYZ,記住係大楷嚟,點解要保留,係因為佢要放喺最尾,目的係要嚟分開而家係分享係頁面定係回覆,同時有其他作用,一陣會講到,另外後尾我發現l同I都係一樣保留咗唔用,我估係因為呢兩個字符太似,容易撈亂,所以唔用
先撇除最後個位唔講,先講前面啲位係點嚟
例如第1個post嘅第2個page係m,一路數落去到第9頁係t,去到第10頁突然跳去bA,點解會咁呢?其實係因為post id + page number變成,例如post id係1而page number係2就變成12,點解12會係m,因為佢係類似base64,但佢又唔係完全base64,經我試驗之後,佢係用a-z之後A-H之後J-R(去到R嘅原因之前講過係因為S-Z係保留咗唔用,另外中間l同I都保留唔用),所以總共係25+17=42個字符,當中佢冇用到數字,所以係42進制,係base42
不過佢同平時嘅進制有少少分別,因為佢冇嘢係代表0,a已經表示1,不過既然毋須表示0,就由得佢就得,直接計唔需要有任何減1操作,所以m等於12,t代表19,而bA就係2*42^1+26=110,(記住R完咗之後佢係用aa再開始而唔係ba,因為就可以慳多啲)
呢度有個表顯示所有字符代表啲咩number:
function base42to10HaveLast(number)
{
let chars = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQR',
radix = chars.length,
numStr = String(number),
len = numStr.length,
i = 0,
originNumber = 0;
while (i < len)
{
originNumber += Math.pow(radix, i++) * (chars.indexOf(numStr.charAt(len - i) || 0)+1);
}
return originNumber;
}
function base10to42HaveLast(number)
{
let chars = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQR'.split(''),
radix = chars.length,
dividend = number,
arr = [];
do
{
mod = dividend % radix;
dividend = (dividend - mod) / radix;
arr.unshift(chars[mod-1]);
}
while (dividend);
return arr.join('');
}
至於點解要用到最尾一個位即係STUVWXYZ,係因為要分辨而家呢個數究竟係代表咩頁數,有分單位數、雙位數、三位數、四位數
例如11112呢個number,我要分出佢係代表邊一個post,同埋邊一頁,最尾個位就係要嚟分,例如如果係第1111個post嘅2頁,就係fmyS,如果係第111個post嘅12頁,就係fmyU,如果係第11個post嘅第112頁,就係fmyW,如果係第1個post嘅第1112頁,就係fmyY,所以我哋可以睇到分享頁面嘅尾數係S U W Y,而分享回覆嘅尾數係T V X Z,所以我哋可以睇到係梅花間竹咁,而因為每邊得4個字符,所以最多去到4個位,即係最多9999就完,唔會多過呢個數,你會話平時頁面得41,回覆得1001,點可以去到9999?因為佢要預留位置,因為有時佢未必去到1001就即時鎖post,有啲會解鎖,好似下面呢個咁,爆post都可以繼續
[集中討論]差佬記者會
- 分享自 LIHKG 討論區
https://lih.kg/krdaNhW
可以去到104頁
而且1001回覆其實就已經係4位數,所以去到4位數都唔太出奇,但佢一定去唔到5位數
分享回覆嘅拆法係一樣,例如qT,要首先將前面變返數字,q係代表16,T即係拎後面一個位,所以即係第1個post嘅第6個回覆
畀多幾個例子
aBcV,前面aBc計完等於2901,V即係後面2個位,所以係第29個post嘅01回覆,由於01所以變返1,所以第29個post嘅第1個回覆
rbCAX,前面rbCA計完等於1264226,X要拆後面3個位,所以係第1264個post嘅第226個回覆
gpNsvZ,前面gpNsv計完等於22961001,Z要拆後面4個位,所以係第2296個post嘅第1001個回覆
你可以試吓lih.kg/aS 會直接出error,咁係因為係a係代表1,用S起碼要去到10先可拆成1同0,就咁1係咩都拆唔到,所以直接error
如果中間用上reserved characters或者數字,例如中間用上STUVWXYZ、Il、0123456789,會直接當0 skip咗佢,但係會霸住個位,例如b1AS,前面b1A,個1字計嘅時候會當0,變成2*42^2+0*42^1+26=3554,所以b1A個1字你插任何reserved characters落去都會計到3554,例如bSA、b8A,所以你入lih.kg/bSAS ,或者lih.kg/b8AS ,都會出一樣嘅嘢
另一方面,我發現如果佢最後一個位並唔係STUVWXYZ,但又唔係全部數字,而係會撈埋英文字母,咁佢會用另一個形式去解析(如果只係數字就係第一種case唔使計直接跳去post id),因為冇咗最後一個位,所以會分唔到係頁面定回覆,所以佢就會直接轉成數字去返嗰個post id,不過今次同上面唔同,佢只係會用全部細楷,所以成件事變成25進制,base 25,因為上面講過a-z 26個字母入面嘅l係唔用,而如果用上reserved characters,今次除咗STUVWXYZ、lI、0123456789之外,連全部大楷嘅字母A-Z都係,用上就會好似上面咁計嘅時候當0 skip咗,下面係幾個例子
bbbb,2*25^3+2*25^2+2*25^1+2=32552,所以直接去post id 32552
bbSbb,2*25^4+2*25^3+0*25^2+2*25^1+2=812552,所以直接去post id 812552
呢個係個表:
Code就同上面差唔多,只係改少少,所以唔寫了
所以其實有5個方法去post id,以去post id 1作為例子
第一, https://lihkg.com/thread/1
第二, lih.kg/kS
第三, lih.kg/1kS
第四, lih.kg/1
第五, lih.kg/a