本文解答:JS如何按自定義格式拼接二進(jìn)制串?如何解析二進(jìn)制串?
當(dāng)你要存一些數(shù)據(jù)時(shí),可以用自定義格式存下來(lái),這樣最節(jié)約空間。
(資料圖片)
例如,你想存這些數(shù)據(jù):
ID(范圍0-16)是否VIP(范圍0-1)星座(范圍0-11)年齡(范圍0-127)那么你可以規(guī)定這種自定義格式的二進(jìn)制串:dddddddc cccbaaaa其中d c b a都是代表0或1,我們用最后4位(aaaa)表示“ID”,用b表示“是否VIP”,用ccc表示“星座”,用dddd表示年齡。
本來(lái)你可能會(huì)用uint32的數(shù)組來(lái)存這些,占4*32=128位,但是現(xiàn)在,我們只用了16位,2個(gè)uint8就存下了。非常節(jié)約存儲(chǔ)空間。這就是一種自定義格式的二進(jìn)制串。
注意:當(dāng)今存儲(chǔ)確實(shí)不貴,但是如果你希望把信息存放到URL中,那么你的空間越小,URL就越短。這時(shí)候價(jià)值就非常大了。例如我之前開(kāi)發(fā)象棋小游戲,把棋局信息(包括當(dāng)前棋盤(pán)狀態(tài)、所有回合操作記錄)都存到了URL中,就能非常方便的保存、分享游戲?qū)?,方便大家?fù)盤(pán)。詳見(jiàn)文章《保存象棋棋盤(pán)信息,需要多少比特?我只用139-167位二進(jìn)制》
在JS中,對(duì)應(yīng)的數(shù)據(jù)類(lèi)型是Uint8Array。
function concatBits(current: number, offset: number, bits: number, bitsLength: number) { let newCurrent = current; let newOffset = offset; const newUint8: number[] = []; if (offset + bitsLength < 8) { newCurrent |= bits << (8 - bitsLength - offset); newOffset += bitsLength; } else if (offset + bitsLength === 8) { newUint8.push(current | bits); newCurrent = 0; newOffset = 0; } else { newCurrent |= bits >> (offset - 8 + bitsLength); newUint8.push(newCurrent); newCurrent = (bits << (16 - offset - bitsLength)) & 0xff; newOffset = offset - 8 + bitsLength; } return [newCurrent, newOffset, newUint8];}當(dāng)然這還是有個(gè)限制:bitsLength必須小于等于8。如果超過(guò)8,可能一個(gè)bits要覆蓋3個(gè)uint8,這種情況沒(méi)考慮在內(nèi)。
如果你需要拓展,歡迎繼續(xù)完善它!
function readBits(array: Uint8Array, bitsOffset: number, bitsLength: number) { const offset = bitsOffset % 8; const index = Math.floor(bitsOffset / 8); if ((offset + bitsLength > 8 && index + 1 >= array.length) || offset + bitsLength <= 8 && index >= array.length) { throw new Error("readBitsError"); } let number = offset + bitsLength <= 8 ? array[index] : (array[index] << 8) | array[index + 1]; const length = offset + bitsLength <= 8 ? 8 : 16; number >>= (length - bitsLength - offset); number &= ([0, 1, 3, 7, 15, 31, 63][bitsLength]); return [number, bitsOffset + bitsLength];}相比encode,decode其實(shí)是更難的事情。
因?yàn)閑ncode時(shí),你只需要無(wú)腦往一個(gè)字節(jié)串后面補(bǔ)充就好。而decode需要你非常清楚,每一位的作用,并理解他們的含義。你需要有高超的位運(yùn)算技巧,才能輕易完成。
設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)時(shí),我們沒(méi)有把項(xiàng)目數(shù)作為一個(gè)變量,所以數(shù)組長(zhǎng)度是未知的。
也就是說(shuō),我們必須不斷循環(huán),直到這個(gè)字節(jié)串沒(méi)有內(nèi)容了,我們就終止。
我們封裝一個(gè)函數(shù)readBits,用于讀取某個(gè)字節(jié)串,從第x位開(kāi)始、長(zhǎng)度為n的內(nèi)容。
因此,需要3個(gè)參數(shù):
字節(jié)串array位偏移量bitsOffset要讀取的長(zhǎng)度bitsLength返回值主要是對(duì)應(yīng)的內(nèi)容(可以用一個(gè)uint8來(lái)表示),此外,讀取后還需要更新一下調(diào)用者的位偏移量bitsOffset,方便持續(xù)調(diào)用,所以我們順便把新的位偏移量bitsOffset返回,作為返回值第二項(xiàng)。
解釋
在本文場(chǎng)景下,要讀取的長(zhǎng)度bitsLength不超過(guò)8,所以我們要關(guān)注的數(shù)據(jù)量,只會(huì)來(lái)自1個(gè)uint8或者某連續(xù)2個(gè)uint8。
計(jì)算index就是為了判斷第一個(gè)關(guān)鍵的uint8的位置。
計(jì)算offset,知道應(yīng)該從index的第幾位開(kāi)始算數(shù)。
然后通過(guò)比較offset + bitsLength和8的大小,就知道我們需要關(guān)注1個(gè)uint8即可、還是需要關(guān)注連續(xù)2個(gè)uint8。
我們把需要關(guān)注的uint8賦值給number,用length表示我們關(guān)注8位還是16位。
例如number二進(jìn)制是10110000,我們需要取從2開(kāi)始的長(zhǎng)度為2的內(nèi)容(即11)。該怎么做呢?
只需要把它右移4位(用于刪除不需要的后綴),再跟二進(jìn)制11做個(gè)與操作(用于刪除不需要的前綴),即可。
因此代碼會(huì)這樣寫(xiě):number >>= (length - bitsLength - offset);number &= ([0, 1, 3, 7, 15, 31, 63][bitsLength]);。
其中0 1 3 7 15 31 63,對(duì)應(yīng)二進(jìn)制分別是0 1 11 111 1111 11111 111111。都是為了刪除前綴。
這里因?yàn)槲倚枰腷itsLength有限,所以我用這種方式偷懶了。如果你要做的更通用,可能要這樣寫(xiě):2 ** bitsLength - 1,目的是獲取位長(zhǎng)度為bitsLength的全是1的數(shù)字,用于刪除number不需要的前綴。
readBits開(kāi)發(fā)完畢,以后可以這樣調(diào)用:
let current;let bitsOffset = 0;[current, bitsOffset] = readBits(array, bitsOffset, 4);這會(huì)讀取字節(jié)串a(chǎn)rray的從第0位開(kāi)始、長(zhǎng)度為4個(gè)bit位的內(nèi)容,賦值給current變量。
我是HullQin,公眾號(hào)線下聚會(huì)游戲的作者(歡迎關(guān)注我,交個(gè)朋友)。轉(zhuǎn)發(fā)本文前需獲得作者HullQin授權(quán)。我獨(dú)立開(kāi)發(fā)了《聯(lián)機(jī)桌游合集》,是個(gè)網(wǎng)頁(yè),可以很方便的跟朋友聯(lián)機(jī)玩UNO、飛行棋、斗地主、五子棋、一夜狼、狼人殺、象棋、德國(guó)心臟病、達(dá)芬奇密碼等游戲,不收費(fèi)無(wú)廣告。還開(kāi)發(fā)了《Dice Crush》參加Game Jam 2022。喜歡可以關(guān)注我噢~我有空了會(huì)分享做游戲的相關(guān)技術(shù),會(huì)在這個(gè)專(zhuān)欄里分享:《教你做小游戲》。
免責(zé)聲明:本文不構(gòu)成任何商業(yè)建議,投資有風(fēng)險(xiǎn),選擇需謹(jǐn)慎!本站發(fā)布的圖文一切為分享交流,傳播正能量,此文不保證數(shù)據(jù)的準(zhǔn)確性,內(nèi)容僅供參考
關(guān)鍵詞:
世界通訊!JS 按自定義格式 拼接二進(jìn)制串 解析二進(jìn)制串
那么你可以規(guī)定這種自定義格式的二進(jìn)制串:dddddddccccbaaaa其中dcba都是代表0或1,我們用最后4位(aaaa)
“奧運(yùn)冠軍之城”鞍山:全民健身浪潮涌動(dòng) 天天關(guān)注
新華社沈陽(yáng)4月23日電(記者李錚、高爽)“只要天氣好,每天我倆都會(huì)到這兒打打球。”22日一早,家住遼寧省
京能熱力:暫無(wú)鍋爐銷(xiāo)售及相關(guān)境外業(yè)務(wù)
京能熱力近期披露投資者關(guān)系活動(dòng)記錄表顯示,公司主營(yíng)業(yè)務(wù)為熱力供應(yīng)、節(jié)能技術(shù)服務(wù),目前暫無(wú)熱電聯(lián)產(chǎn)項(xiàng)目
熱點(diǎn)評(píng)!世錦賽開(kāi)門(mén)紅!中國(guó)男子冰球隊(duì)5比4擊敗烏克蘭隊(duì)
北京時(shí)間23日,2023年國(guó)際冰聯(lián)男子冰球世錦賽甲級(jí)B組比賽在愛(ài)沙尼亞塔林進(jìn)行,中國(guó)男子冰球隊(duì)首戰(zhàn)以5∶4戰(zhàn)
維金斯復(fù)出就找回狀態(tài)!克萊:不可思議 而且他看起來(lái)也沒(méi)太努力|環(huán)球今日?qǐng)?bào)
直播吧4月24日訊今日季后賽首輪G4,勇士主場(chǎng)126-125戰(zhàn)勝國(guó)王,將大比分扳為2-2平。勇士球星克萊-湯普森賽后接
寧德時(shí)代回應(yīng)原材料價(jià)格下跌:已充分考慮相關(guān)影響,不存在大幅減值風(fēng)險(xiǎn)
上證報(bào)中國(guó)證券網(wǎng)訊(記者邱德坤)4月24日,寧德時(shí)代在互動(dòng)平臺(tái)表示,針對(duì)原材料價(jià)格下跌對(duì)業(yè)績(jī)的影響,公
《灌籃高手》4天3.8億,今年五一檔前有狼后有虎,國(guó)片當(dāng)自強(qiáng)_動(dòng)態(tài)
《灌籃高手》4天3 8億,今年五一檔前有狼后有虎,國(guó)片當(dāng)自強(qiáng),票房,動(dòng)畫(huà)片,灌籃高手,動(dòng)畫(huà)電影,井上雄彥,校園
今日要聞!《半熟男女》今日低調(diào)開(kāi)機(jī) 田曦薇辛云來(lái)張哲華新鮮組合引期待
半熟男女電視劇開(kāi)機(jī)
黔江區(qū)開(kāi)展非物質(zhì)文化遺產(chǎn)傳承創(chuàng)新能力提升培訓(xùn)-環(huán)球聚焦
2023年4月24日11:57?來(lái)源:中新網(wǎng)重慶
高曉松前妻沈歡又嫁人 高曉松前妻沈歡現(xiàn)狀
今天來(lái)聊聊關(guān)于高曉松前妻沈歡又嫁人,高曉松前妻沈歡現(xiàn)狀的文章,現(xiàn)在就為大家來(lái)簡(jiǎn)單介紹下高曉松前妻沈歡
即時(shí)看!Reach for the stars
ChinaiscelebratingitseighthSpace...
新能源車(chē)成2023上海車(chē)展絕對(duì)主流-最新資訊
上海連續(xù)多日近30度的氣溫已讓人提...
天天播報(bào):用讀書(shū)充實(shí)生活 前行的腳步會(huì)更有力量
新聞背景:4月23日,第28個(gè)世界讀...
世界熱議:U.S. world's No. 1 stealer of secrets
ByTanXiguangAbatchofclassifieddo...
中國(guó)星辰丨宇宙級(jí)考驗(yàn),在太空中“蓋房子”需要滿足什么條件?
中國(guó)載人航天誕生于怎樣的時(shí)代風(fēng)云...
全球觀焦點(diǎn):Chang'e 8 to test use of 3D printing tech to build on moon
PhototakenbytheroverYutu2(JadeRa...
國(guó)家知識(shí)產(chǎn)權(quán)局:嚴(yán)厲打擊商標(biāo)惡意注冊(cè)行為 特別是傍名牌、搭便車(chē)等 世界視點(diǎn)
央視網(wǎng)消息:4月24日10時(shí),國(guó)務(wù)院...
今日要聞!《半熟男女》今日低調(diào)開(kāi)機(jī) 田曦薇辛云來(lái)張哲華新鮮組合引期待
半熟男女電視劇開(kāi)機(jī)
黔江區(qū)開(kāi)展非物質(zhì)文化遺產(chǎn)傳承創(chuàng)新能力提升培訓(xùn)-環(huán)球聚焦
2023年4月24日11:57?來(lái)源:中新網(wǎng)重慶
高曉松前妻沈歡又嫁人 高曉松前妻沈歡現(xiàn)狀
今天來(lái)聊聊關(guān)于高曉松前妻沈歡又嫁...
【世界新視野】交通運(yùn)輸部要求嚴(yán)格落實(shí)重大節(jié)假日免收小型客車(chē)通行費(fèi)政策
記者23日從交通運(yùn)輸部獲悉,針對(duì)“...