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