Skip to content

Instantly share code, notes, and snippets.

@0x1d107
Last active November 4, 2025 08:52
Show Gist options
  • Select an option

  • Save 0x1d107/6835358af82884d064341fca1b311725 to your computer and use it in GitHub Desktop.

Select an option

Save 0x1d107/6835358af82884d064341fca1b311725 to your computer and use it in GitHub Desktop.

Bookmarklets

Bookmarklets are tiny pieces of javascript code stored as a bookmark with javascript: URL scheme. They're often used to extend functionality of a third-party website.

My bookmarklets

Urls in the parentheses indicate which website the bookmarklet is intended to work on.

  1. ytsavetime.js (https://youtube.com) -- saves current play time in localstorage.
  2. FuckRBooks.js (https://e-library.ufa-rb.ru/) -- bookmarklet that allows to print the book. Uses a large amount of RAM.
  3. libDL.js (https://e.lanbook.com) -- allows to download PDF from the site.
  4. stroki-download.js (https://stroki.mts.ru) -- allows to download EPUB books for PC

ytsavetime.js

javascript:(()%3D%3E%7Bvar%20e%3Ddocument.querySelector.bind(document)(%22video%22)%2Ct%3Dnew%20URL(document.location).searchParams%3Bfunction%20n()%7Breturn%20null!%3D%3Dt.get(%22v%22)%3Ft.get(%22v%22)%3Ae.src%7Dfunction%20r()%7BlocalStorage.setItem(n()%2Ce.currentTime)%7Dnull%3D%3D%3Dt.get(%22t%22)%26%26function()%7Bvar%20t%3DlocalStorage.getItem(n())%3Bt%26%26(e.duration-t%3E5%3Fe.currentTime%3Dt%3A(e.currentTime%3D0%2Cr()))%7D()%2Ce.addEventListener(%22timeupdate%22%2Cfunction(e)%7Br()%7D)%7D)()%3B)

FuckRBooks.js

javascript:(function()%7Bdocument.getElementById('rBooks').contentWindow.PDFViewerApplication.findController._pdfDocument.mAllowPrint%20%3D%20true%3B%0Adocument.getElementById('rBooks').contentDocument.getElementById('print').click()%3B%7D)()%3B

libDL.js

javascript:(()%3D%3E%7Bvar%20o%3Dlocation.href.match(%22book%2F%5B0-9%5D%2B%22)%5B0%5D.split(%22%2F%22)%5B1%5D%2Ce%3Ddocument.cookie.matchAll(%22lan_access_token%3D(%5B%5E%3B%5D%2B)%22).next().value%5B1%5D%3Bdocument.location.href%3D%60https%3A%2F%2Freader.lanbook.com%2Fapi%2Fv2%2Fbook%2F%24%7Bo%7D%2FdocumentFile%3FjwtToken%3D%24%7Be%7D%60%7D)()%3B

stroki-download.js

javascript:(async%20function()%7Blet%20book_id%20%3D%20parseInt(document.location.href.split('-').at(-1))%3B%0Alet%20access_token%20%3D%20localStorage.token%3B%0Alet%20install_guid%20%3D%20localStorage%5B'install-guid'%5D%3B%0Alet%20settings%20%3D%20JSON.parse(localStorage.settings)%3B%0Alet%20api_url%20%3D%20%22https%3A%2F%2Fstroki.mts.ru%2Fapi%2F%22%3B%0Afunction%20signUrl(url)%7B%0A%09return%20hex_md5(url.replace(%22https%3A%22%2C%22http%3A%22)%2B%22meg%40%24h!t%22)%3B%0A%7D%0Afunction%20makeHeaders(url%2Cver%3D'6.0')%7B%0A%09return%20%7B%0A%09%09%22app-version%22%3Asettings.version%2C%0A%09%09%22access-token%22%3Aaccess_token%2C%0A%09%09%22api-version%22%3Aver%2C%0A%09%09%22install-guid%22%3Ainstall_guid%2C%0A%09%09%22access-token%22%3Aaccess_token%2C%0A%09%09%22signature%22%3AsignUrl(url)%2C%0A%09%09%22platform%22%3A%22Web%22%2C%0A%09%09%22device-model%22%3A%22Macintosh%22%2C%0A%09%09%22device-type%22%3A%22PC%22%2C%0A%09%09%22requestId%22%3Acrypto.randomUUID()%2C%0A%09%09%22country%22%3A%22RU%22%2C%0A%09%09%22language%22%3A%22en%22%2C%0A%09%09%22traceId%22%3Acrypto.randomUUID()%0A%0A%09%7D%0A%7D%0Aasync%20function%20getFileId(bookid)%7B%0A%09let%20u%20%3D%20api_url%2B%22books%2F%22%2Bbookid%2B%22%2Ffiles%22%3B%0A%09return%20await%20fetch(u%2C%7Bheaders%3AmakeHeaders(u)%7D).then(x%3D%3Ex.json()).then(x%3D%3Ex.data.full%5B0%5D.fileId)%0A%7D%0Aasync%20function%20downloadFile(fileid)%7B%0A%09let%20u%20%3D%20api_url%2B%22books%2Ffiles%2Fdata%2F%22%2Bfileid%3B%0A%09return%20await%20fetch(u%2C%7Bheaders%3AmakeHeaders(u%2C%225.0%22)%7D)%0A%09%09.then(x%3D%3Ex.blob())%0A%09%09.then(x%3D%3Ewindow.location.assign(window.URL.createObjectURL(x)))%3B%0A%7D%0Aawait%20downloadFile(await%20getFileId(book_id))%3B%0A%2F*%0A%20*%20A%20JavaScript%20implementation%20of%20the%20RSA%20Data%20Security%2C%20Inc.%20MD5%20Message%0A%20*%20Digest%20Algorithm%2C%20as%20defined%20in%20RFC%201321.%0A%20*%20Version%202.2%20Copyright%20(C)%20Paul%20Johnston%201999%20-%202009%0A%20*%20Other%20contributors%3A%20Greg%20Holt%2C%20Andrew%20Kepert%2C%20Ydnar%2C%20Lostinet%0A%20*%20Distributed%20under%20the%20BSD%20License%0A%20*%20See%20http%3A%2F%2Fpajhome.org.uk%2Fcrypt%2Fmd5%20for%20more%20info.%0A%20*%2F%0A%0A%2F*%0A%20*%20Configurable%20variables.%20You%20may%20need%20to%20tweak%20these%20to%20be%20compatible%20with%0A%20*%20the%20server-side%2C%20but%20the%20defaults%20work%20in%20most%20cases.%0A%20*%2F%0Avar%20hexcase%20%3D%200%3B%20%20%20%2F*%20hex%20output%20format.%200%20-%20lowercase%3B%201%20-%20uppercase%20%20%20%20%20%20%20%20*%2F%0Avar%20b64pad%20%20%3D%20%22%22%3B%20%20%2F*%20base-64%20pad%20character.%20%22%3D%22%20for%20strict%20RFC%20compliance%20%20%20*%2F%0A%0A%2F*%0A%20*%20These%20are%20the%20functions%20you'll%20usually%20want%20to%20call%0A%20*%20They%20take%20string%20arguments%20and%20return%20either%20hex%20or%20base-64%20encoded%20strings%0A%20*%2F%0Afunction%20hex_md5(s)%20%20%20%20%7B%20return%20rstr2hex(rstr_md5(str2rstr_utf8(s)))%3B%20%7D%0A%0A%2F*%0A%20*%20Calculate%20the%20MD5%20of%20a%20raw%20string%0A%20*%2F%0Afunction%20rstr_md5(s)%0A%7B%0A%20%20return%20binl2rstr(binl_md5(rstr2binl(s)%2C%20s.length%20*%208))%3B%0A%7D%0A%0A%2F*%0A%20*%20Convert%20a%20raw%20string%20to%20a%20hex%20string%0A%20*%2F%0Afunction%20rstr2hex(input)%0A%7B%0A%20%20try%20%7B%20hexcase%20%7D%20catch(e)%20%7B%20hexcase%3D0%3B%20%7D%0A%20%20var%20hex_tab%20%3D%20hexcase%20%3F%20%220123456789ABCDEF%22%20%3A%20%220123456789abcdef%22%3B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20var%20x%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20input.length%3B%20i%2B%2B)%0A%20%20%7B%0A%20%20%20%20x%20%3D%20input.charCodeAt(i)%3B%0A%20%20%20%20output%20%2B%3D%20hex_tab.charAt((x%20%3E%3E%3E%204)%20%26%200x0F)%0A%20%20%20%20%20%20%20%20%20%20%20%2B%20%20hex_tab.charAt(%20x%20%20%20%20%20%20%20%20%26%200x0F)%3B%0A%20%20%7D%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Convert%20a%20raw%20string%20to%20a%20base-64%20string%0A%20*%2F%0Afunction%20rstr2b64(input)%0A%7B%0A%20%20try%20%7B%20b64pad%20%7D%20catch(e)%20%7B%20b64pad%3D''%3B%20%7D%0A%20%20var%20tab%20%3D%20%22ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%2B%2F%22%3B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20var%20len%20%3D%20input.length%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20len%3B%20i%20%2B%3D%203)%0A%20%20%7B%0A%20%20%20%20var%20triplet%20%3D%20(input.charCodeAt(i)%20%3C%3C%2016)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20(i%20%2B%201%20%3C%20len%20%3F%20input.charCodeAt(i%2B1)%20%3C%3C%208%20%3A%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20(i%20%2B%202%20%3C%20len%20%3F%20input.charCodeAt(i%2B2)%20%20%20%20%20%20%3A%200)%3B%0A%20%20%20%20for(var%20j%20%3D%200%3B%20j%20%3C%204%3B%20j%2B%2B)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20if(i%20*%208%20%2B%20j%20*%206%20%3E%20input.length%20*%208)%20output%20%2B%3D%20b64pad%3B%0A%20%20%20%20%20%20else%20output%20%2B%3D%20tab.charAt((triplet%20%3E%3E%3E%206*(3-j))%20%26%200x3F)%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Convert%20a%20raw%20string%20to%20an%20arbitrary%20string%20encoding%0A%20*%2F%0Afunction%20rstr2any(input%2C%20encoding)%0A%7B%0A%20%20var%20divisor%20%3D%20encoding.length%3B%0A%20%20var%20i%2C%20j%2C%20q%2C%20x%2C%20quotient%3B%0A%0A%20%20%2F*%20Convert%20to%20an%20array%20of%2016-bit%20big-endian%20values%2C%20forming%20the%20dividend%20*%2F%0A%20%20var%20dividend%20%3D%20Array(Math.ceil(input.length%20%2F%202))%3B%0A%20%20for(i%20%3D%200%3B%20i%20%3C%20dividend.length%3B%20i%2B%2B)%0A%20%20%7B%0A%20%20%20%20dividend%5Bi%5D%20%3D%20(input.charCodeAt(i%20*%202)%20%3C%3C%208)%20%7C%20input.charCodeAt(i%20*%202%20%2B%201)%3B%0A%20%20%7D%0A%0A%20%20%2F*%0A%20%20%20*%20Repeatedly%20perform%20a%20long%20division.%20The%20binary%20array%20forms%20the%20dividend%2C%0A%20%20%20*%20the%20length%20of%20the%20encoding%20is%20the%20divisor.%20Once%20computed%2C%20the%20quotient%0A%20%20%20*%20forms%20the%20dividend%20for%20the%20next%20step.%20All%20remainders%20are%20stored%20for%20later%0A%20%20%20*%20use.%0A%20%20%20*%2F%0A%20%20var%20full_length%20%3D%20Math.ceil(input.length%20*%208%20%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Math.log(encoding.length)%20%2F%20Math.log(2)))%3B%0A%20%20var%20remainders%20%3D%20Array(full_length)%3B%0A%20%20for(j%20%3D%200%3B%20j%20%3C%20full_length%3B%20j%2B%2B)%0A%20%20%7B%0A%20%20%20%20quotient%20%3D%20Array()%3B%0A%20%20%20%20x%20%3D%200%3B%0A%20%20%20%20for(i%20%3D%200%3B%20i%20%3C%20dividend.length%3B%20i%2B%2B)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20x%20%3D%20(x%20%3C%3C%2016)%20%2B%20dividend%5Bi%5D%3B%0A%20%20%20%20%20%20q%20%3D%20Math.floor(x%20%2F%20divisor)%3B%0A%20%20%20%20%20%20x%20-%3D%20q%20*%20divisor%3B%0A%20%20%20%20%20%20if(quotient.length%20%3E%200%20%7C%7C%20q%20%3E%200)%0A%20%20%20%20%20%20%20%20quotient%5Bquotient.length%5D%20%3D%20q%3B%0A%20%20%20%20%7D%0A%20%20%20%20remainders%5Bj%5D%20%3D%20x%3B%0A%20%20%20%20dividend%20%3D%20quotient%3B%0A%20%20%7D%0A%0A%20%20%2F*%20Convert%20the%20remainders%20to%20the%20output%20string%20*%2F%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20for(i%20%3D%20remainders.length%20-%201%3B%20i%20%3E%3D%200%3B%20i--)%0A%20%20%20%20output%20%2B%3D%20encoding.charAt(remainders%5Bi%5D)%3B%0A%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Encode%20a%20string%20as%20utf-8.%0A%20*%20For%20efficiency%2C%20this%20assumes%20the%20input%20is%20valid%20utf-16.%0A%20*%2F%0Afunction%20str2rstr_utf8(input)%0A%7B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20var%20i%20%3D%20-1%3B%0A%20%20var%20x%2C%20y%3B%0A%0A%20%20while(%2B%2Bi%20%3C%20input.length)%0A%20%20%7B%0A%20%20%20%20%2F*%20Decode%20utf-16%20surrogate%20pairs%20*%2F%0A%20%20%20%20x%20%3D%20input.charCodeAt(i)%3B%0A%20%20%20%20y%20%3D%20i%20%2B%201%20%3C%20input.length%20%3F%20input.charCodeAt(i%20%2B%201)%20%3A%200%3B%0A%20%20%20%20if(0xD800%20%3C%3D%20x%20%26%26%20x%20%3C%3D%200xDBFF%20%26%26%200xDC00%20%3C%3D%20y%20%26%26%20y%20%3C%3D%200xDFFF)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20x%20%3D%200x10000%20%2B%20((x%20%26%200x03FF)%20%3C%3C%2010)%20%2B%20(y%20%26%200x03FF)%3B%0A%20%20%20%20%20%20i%2B%2B%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F*%20Encode%20output%20as%20utf-8%20*%2F%0A%20%20%20%20if(x%20%3C%3D%200x7F)%0A%20%20%20%20%20%20output%20%2B%3D%20String.fromCharCode(x)%3B%0A%20%20%20%20else%20if(x%20%3C%3D%200x7FF)%0A%20%20%20%20%20%20output%20%2B%3D%20String.fromCharCode(0xC0%20%7C%20((x%20%3E%3E%3E%206%20)%20%26%200x1F)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20(%20x%20%20%20%20%20%20%20%20%20%26%200x3F))%3B%0A%20%20%20%20else%20if(x%20%3C%3D%200xFFFF)%0A%20%20%20%20%20%20output%20%2B%3D%20String.fromCharCode(0xE0%20%7C%20((x%20%3E%3E%3E%2012)%20%26%200x0F)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20((x%20%3E%3E%3E%206%20)%20%26%200x3F)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20(%20x%20%20%20%20%20%20%20%20%20%26%200x3F))%3B%0A%20%20%20%20else%20if(x%20%3C%3D%200x1FFFFF)%0A%20%20%20%20%20%20output%20%2B%3D%20String.fromCharCode(0xF0%20%7C%20((x%20%3E%3E%3E%2018)%20%26%200x07)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20((x%20%3E%3E%3E%2012)%20%26%200x3F)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20((x%20%3E%3E%3E%206%20)%20%26%200x3F)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200x80%20%7C%20(%20x%20%20%20%20%20%20%20%20%20%26%200x3F))%3B%0A%20%20%7D%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Encode%20a%20string%20as%20utf-16%0A%20*%2F%0Afunction%20str2rstr_utf16le(input)%0A%7B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20input.length%3B%20i%2B%2B)%0A%20%20%20%20output%20%2B%3D%20String.fromCharCode(%20input.charCodeAt(i)%20%20%20%20%20%20%20%20%26%200xFF%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(input.charCodeAt(i)%20%3E%3E%3E%208)%20%26%200xFF)%3B%0A%20%20return%20output%3B%0A%7D%0A%0Afunction%20str2rstr_utf16be(input)%0A%7B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20input.length%3B%20i%2B%2B)%0A%20%20%20%20output%20%2B%3D%20String.fromCharCode((input.charCodeAt(i)%20%3E%3E%3E%208)%20%26%200xFF%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20input.charCodeAt(i)%20%20%20%20%20%20%20%20%26%200xFF)%3B%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Convert%20a%20raw%20string%20to%20an%20array%20of%20little-endian%20words%0A%20*%20Characters%20%3E255%20have%20their%20high-byte%20silently%20ignored.%0A%20*%2F%0Afunction%20rstr2binl(input)%0A%7B%0A%20%20var%20output%20%3D%20Array(input.length%20%3E%3E%202)%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20output.length%3B%20i%2B%2B)%0A%20%20%20%20output%5Bi%5D%20%3D%200%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20input.length%20*%208%3B%20i%20%2B%3D%208)%0A%20%20%20%20output%5Bi%3E%3E5%5D%20%7C%3D%20(input.charCodeAt(i%20%2F%208)%20%26%200xFF)%20%3C%3C%20(i%2532)%3B%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Convert%20an%20array%20of%20little-endian%20words%20to%20a%20string%0A%20*%2F%0Afunction%20binl2rstr(input)%0A%7B%0A%20%20var%20output%20%3D%20%22%22%3B%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20input.length%20*%2032%3B%20i%20%2B%3D%208)%0A%20%20%20%20output%20%2B%3D%20String.fromCharCode((input%5Bi%3E%3E5%5D%20%3E%3E%3E%20(i%20%25%2032))%20%26%200xFF)%3B%0A%20%20return%20output%3B%0A%7D%0A%0A%2F*%0A%20*%20Calculate%20the%20MD5%20of%20an%20array%20of%20little-endian%20words%2C%20and%20a%20bit%20length.%0A%20*%2F%0Afunction%20binl_md5(x%2C%20len)%0A%7B%0A%20%20%2F*%20append%20padding%20*%2F%0A%20%20x%5Blen%20%3E%3E%205%5D%20%7C%3D%200x80%20%3C%3C%20((len)%20%25%2032)%3B%0A%20%20x%5B(((len%20%2B%2064)%20%3E%3E%3E%209)%20%3C%3C%204)%20%2B%2014%5D%20%3D%20len%3B%0A%0A%20%20var%20a%20%3D%20%201732584193%3B%0A%20%20var%20b%20%3D%20-271733879%3B%0A%20%20var%20c%20%3D%20-1732584194%3B%0A%20%20var%20d%20%3D%20%20271733878%3B%0A%0A%20%20for(var%20i%20%3D%200%3B%20i%20%3C%20x.length%3B%20i%20%2B%3D%2016)%0A%20%20%7B%0A%20%20%20%20var%20olda%20%3D%20a%3B%0A%20%20%20%20var%20oldb%20%3D%20b%3B%0A%20%20%20%20var%20oldc%20%3D%20c%3B%0A%20%20%20%20var%20oldd%20%3D%20d%3B%0A%0A%20%20%20%20a%20%3D%20md5_ff(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%200%5D%2C%207%20%2C%20-680876936)%3B%0A%20%20%20%20d%20%3D%20md5_ff(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%201%5D%2C%2012%2C%20-389564586)%3B%0A%20%20%20%20c%20%3D%20md5_ff(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%202%5D%2C%2017%2C%20%20606105819)%3B%0A%20%20%20%20b%20%3D%20md5_ff(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%203%5D%2C%2022%2C%20-1044525330)%3B%0A%20%20%20%20a%20%3D%20md5_ff(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%204%5D%2C%207%20%2C%20-176418897)%3B%0A%20%20%20%20d%20%3D%20md5_ff(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%205%5D%2C%2012%2C%20%201200080426)%3B%0A%20%20%20%20c%20%3D%20md5_ff(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%206%5D%2C%2017%2C%20-1473231341)%3B%0A%20%20%20%20b%20%3D%20md5_ff(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%207%5D%2C%2022%2C%20-45705983)%3B%0A%20%20%20%20a%20%3D%20md5_ff(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%208%5D%2C%207%20%2C%20%201770035416)%3B%0A%20%20%20%20d%20%3D%20md5_ff(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%209%5D%2C%2012%2C%20-1958414417)%3B%0A%20%20%20%20c%20%3D%20md5_ff(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B10%5D%2C%2017%2C%20-42063)%3B%0A%20%20%20%20b%20%3D%20md5_ff(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B11%5D%2C%2022%2C%20-1990404162)%3B%0A%20%20%20%20a%20%3D%20md5_ff(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B12%5D%2C%207%20%2C%20%201804603682)%3B%0A%20%20%20%20d%20%3D%20md5_ff(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B13%5D%2C%2012%2C%20-40341101)%3B%0A%20%20%20%20c%20%3D%20md5_ff(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B14%5D%2C%2017%2C%20-1502002290)%3B%0A%20%20%20%20b%20%3D%20md5_ff(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B15%5D%2C%2022%2C%20%201236535329)%3B%0A%0A%20%20%20%20a%20%3D%20md5_gg(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%201%5D%2C%205%20%2C%20-165796510)%3B%0A%20%20%20%20d%20%3D%20md5_gg(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%206%5D%2C%209%20%2C%20-1069501632)%3B%0A%20%20%20%20c%20%3D%20md5_gg(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B11%5D%2C%2014%2C%20%20643717713)%3B%0A%20%20%20%20b%20%3D%20md5_gg(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%200%5D%2C%2020%2C%20-373897302)%3B%0A%20%20%20%20a%20%3D%20md5_gg(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%205%5D%2C%205%20%2C%20-701558691)%3B%0A%20%20%20%20d%20%3D%20md5_gg(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B10%5D%2C%209%20%2C%20%2038016083)%3B%0A%20%20%20%20c%20%3D%20md5_gg(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B15%5D%2C%2014%2C%20-660478335)%3B%0A%20%20%20%20b%20%3D%20md5_gg(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%204%5D%2C%2020%2C%20-405537848)%3B%0A%20%20%20%20a%20%3D%20md5_gg(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%209%5D%2C%205%20%2C%20%20568446438)%3B%0A%20%20%20%20d%20%3D%20md5_gg(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B14%5D%2C%209%20%2C%20-1019803690)%3B%0A%20%20%20%20c%20%3D%20md5_gg(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%203%5D%2C%2014%2C%20-187363961)%3B%0A%20%20%20%20b%20%3D%20md5_gg(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%208%5D%2C%2020%2C%20%201163531501)%3B%0A%20%20%20%20a%20%3D%20md5_gg(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B13%5D%2C%205%20%2C%20-1444681467)%3B%0A%20%20%20%20d%20%3D%20md5_gg(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%202%5D%2C%209%20%2C%20-51403784)%3B%0A%20%20%20%20c%20%3D%20md5_gg(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%207%5D%2C%2014%2C%20%201735328473)%3B%0A%20%20%20%20b%20%3D%20md5_gg(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B12%5D%2C%2020%2C%20-1926607734)%3B%0A%0A%20%20%20%20a%20%3D%20md5_hh(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%205%5D%2C%204%20%2C%20-378558)%3B%0A%20%20%20%20d%20%3D%20md5_hh(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%208%5D%2C%2011%2C%20-2022574463)%3B%0A%20%20%20%20c%20%3D%20md5_hh(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B11%5D%2C%2016%2C%20%201839030562)%3B%0A%20%20%20%20b%20%3D%20md5_hh(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B14%5D%2C%2023%2C%20-35309556)%3B%0A%20%20%20%20a%20%3D%20md5_hh(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%201%5D%2C%204%20%2C%20-1530992060)%3B%0A%20%20%20%20d%20%3D%20md5_hh(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%204%5D%2C%2011%2C%20%201272893353)%3B%0A%20%20%20%20c%20%3D%20md5_hh(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%207%5D%2C%2016%2C%20-155497632)%3B%0A%20%20%20%20b%20%3D%20md5_hh(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B10%5D%2C%2023%2C%20-1094730640)%3B%0A%20%20%20%20a%20%3D%20md5_hh(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B13%5D%2C%204%20%2C%20%20681279174)%3B%0A%20%20%20%20d%20%3D%20md5_hh(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%200%5D%2C%2011%2C%20-358537222)%3B%0A%20%20%20%20c%20%3D%20md5_hh(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%203%5D%2C%2016%2C%20-722521979)%3B%0A%20%20%20%20b%20%3D%20md5_hh(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%206%5D%2C%2023%2C%20%2076029189)%3B%0A%20%20%20%20a%20%3D%20md5_hh(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%209%5D%2C%204%20%2C%20-640364487)%3B%0A%20%20%20%20d%20%3D%20md5_hh(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B12%5D%2C%2011%2C%20-421815835)%3B%0A%20%20%20%20c%20%3D%20md5_hh(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B15%5D%2C%2016%2C%20%20530742520)%3B%0A%20%20%20%20b%20%3D%20md5_hh(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%202%5D%2C%2023%2C%20-995338651)%3B%0A%0A%20%20%20%20a%20%3D%20md5_ii(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%200%5D%2C%206%20%2C%20-198630844)%3B%0A%20%20%20%20d%20%3D%20md5_ii(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%207%5D%2C%2010%2C%20%201126891415)%3B%0A%20%20%20%20c%20%3D%20md5_ii(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B14%5D%2C%2015%2C%20-1416354905)%3B%0A%20%20%20%20b%20%3D%20md5_ii(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%205%5D%2C%2021%2C%20-57434055)%3B%0A%20%20%20%20a%20%3D%20md5_ii(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B12%5D%2C%206%20%2C%20%201700485571)%3B%0A%20%20%20%20d%20%3D%20md5_ii(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B%203%5D%2C%2010%2C%20-1894986606)%3B%0A%20%20%20%20c%20%3D%20md5_ii(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B10%5D%2C%2015%2C%20-1051523)%3B%0A%20%20%20%20b%20%3D%20md5_ii(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%201%5D%2C%2021%2C%20-2054922799)%3B%0A%20%20%20%20a%20%3D%20md5_ii(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%208%5D%2C%206%20%2C%20%201873313359)%3B%0A%20%20%20%20d%20%3D%20md5_ii(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B15%5D%2C%2010%2C%20-30611744)%3B%0A%20%20%20%20c%20%3D%20md5_ii(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%206%5D%2C%2015%2C%20-1560198380)%3B%0A%20%20%20%20b%20%3D%20md5_ii(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B13%5D%2C%2021%2C%20%201309151649)%3B%0A%20%20%20%20a%20%3D%20md5_ii(a%2C%20b%2C%20c%2C%20d%2C%20x%5Bi%2B%204%5D%2C%206%20%2C%20-145523070)%3B%0A%20%20%20%20d%20%3D%20md5_ii(d%2C%20a%2C%20b%2C%20c%2C%20x%5Bi%2B11%5D%2C%2010%2C%20-1120210379)%3B%0A%20%20%20%20c%20%3D%20md5_ii(c%2C%20d%2C%20a%2C%20b%2C%20x%5Bi%2B%202%5D%2C%2015%2C%20%20718787259)%3B%0A%20%20%20%20b%20%3D%20md5_ii(b%2C%20c%2C%20d%2C%20a%2C%20x%5Bi%2B%209%5D%2C%2021%2C%20-343485551)%3B%0A%0A%20%20%20%20a%20%3D%20safe_add(a%2C%20olda)%3B%0A%20%20%20%20b%20%3D%20safe_add(b%2C%20oldb)%3B%0A%20%20%20%20c%20%3D%20safe_add(c%2C%20oldc)%3B%0A%20%20%20%20d%20%3D%20safe_add(d%2C%20oldd)%3B%0A%20%20%7D%0A%20%20return%20Array(a%2C%20b%2C%20c%2C%20d)%3B%0A%7D%0A%0A%2F*%0A%20*%20These%20functions%20implement%20the%20four%20basic%20operations%20the%20algorithm%20uses.%0A%20*%2F%0Afunction%20md5_cmn(q%2C%20a%2C%20b%2C%20x%2C%20s%2C%20t)%0A%7B%0A%20%20return%20safe_add(bit_rol(safe_add(safe_add(a%2C%20q)%2C%20safe_add(x%2C%20t))%2C%20s)%2Cb)%3B%0A%7D%0Afunction%20md5_ff(a%2C%20b%2C%20c%2C%20d%2C%20x%2C%20s%2C%20t)%0A%7B%0A%20%20return%20md5_cmn((b%20%26%20c)%20%7C%20((~b)%20%26%20d)%2C%20a%2C%20b%2C%20x%2C%20s%2C%20t)%3B%0A%7D%0Afunction%20md5_gg(a%2C%20b%2C%20c%2C%20d%2C%20x%2C%20s%2C%20t)%0A%7B%0A%20%20return%20md5_cmn((b%20%26%20d)%20%7C%20(c%20%26%20(~d))%2C%20a%2C%20b%2C%20x%2C%20s%2C%20t)%3B%0A%7D%0Afunction%20md5_hh(a%2C%20b%2C%20c%2C%20d%2C%20x%2C%20s%2C%20t)%0A%7B%0A%20%20return%20md5_cmn(b%20%5E%20c%20%5E%20d%2C%20a%2C%20b%2C%20x%2C%20s%2C%20t)%3B%0A%7D%0Afunction%20md5_ii(a%2C%20b%2C%20c%2C%20d%2C%20x%2C%20s%2C%20t)%0A%7B%0A%20%20return%20md5_cmn(c%20%5E%20(b%20%7C%20(~d))%2C%20a%2C%20b%2C%20x%2C%20s%2C%20t)%3B%0A%7D%0A%0A%2F*%0A%20*%20Add%20integers%2C%20wrapping%20at%202%5E32.%20This%20uses%2016-bit%20operations%20internally%0A%20*%20to%20work%20around%20bugs%20in%20some%20JS%20interpreters.%0A%20*%2F%0Afunction%20safe_add(x%2C%20y)%0A%7B%0A%20%20var%20lsw%20%3D%20(x%20%26%200xFFFF)%20%2B%20(y%20%26%200xFFFF)%3B%0A%20%20var%20msw%20%3D%20(x%20%3E%3E%2016)%20%2B%20(y%20%3E%3E%2016)%20%2B%20(lsw%20%3E%3E%2016)%3B%0A%20%20return%20(msw%20%3C%3C%2016)%20%7C%20(lsw%20%26%200xFFFF)%3B%0A%7D%0A%0A%2F*%0A%20*%20Bitwise%20rotate%20a%2032-bit%20number%20to%20the%20left.%0A%20*%2F%0Afunction%20bit_rol(num%2C%20cnt)%0A%7B%0A%20%20return%20(num%20%3C%3C%20cnt)%20%7C%20(num%20%3E%3E%3E%20(32%20-%20cnt))%3B%0A%7D%7D)()%3B
let book_id = parseInt(document.location.href.split('-').at(-1));
let access_token = localStorage.token;
let install_guid = localStorage['install-guid'];
let settings = JSON.parse(localStorage.settings);
let api_url = "https://stroki.mts.ru/api/";
function signUrl(url){
return hex_md5(url.replace("https:","http:")+"meg@$h!t");
}
function makeHeaders(url,ver='6.0'){
return {
"app-version":settings.version,
"access-token":access_token,
"api-version":ver,
"install-guid":install_guid,
"access-token":access_token,
"signature":signUrl(url),
"platform":"Web",
"device-model":"Macintosh",
"device-type":"PC",
"requestId":crypto.randomUUID(),
"country":"RU",
"language":"en",
"traceId":crypto.randomUUID()
}
}
async function getFileId(bookid){
let u = api_url+"books/"+bookid+"/files";
return await fetch(u,{headers:makeHeaders(u)}).then(x=>x.json()).then(x=>x.data.full[0].fileId)
}
async function downloadFile(fileid){
let u = api_url+"books/files/data/"+fileid;
return await fetch(u,{headers:makeHeaders(u,"5.0")})
.then(x=>x.blob())
.then(x=>window.location.assign(window.URL.createObjectURL(x)));
}
await downloadFile(await getFileId(book_id));
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
/*
* Calculate the MD5 of a raw string
*/
function rstr_md5(s)
{
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
}
/*
* Convert a raw string to a hex string
*/
function rstr2hex(input)
{
try { hexcase } catch(e) { hexcase=0; }
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
var x;
for(var i = 0; i < input.length; i++)
{
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F)
+ hex_tab.charAt( x & 0x0F);
}
return output;
}
/*
* Convert a raw string to a base-64 string
*/
function rstr2b64(input)
{
try { b64pad } catch(e) { b64pad=''; }
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var output = "";
var len = input.length;
for(var i = 0; i < len; i += 3)
{
var triplet = (input.charCodeAt(i) << 16)
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
for(var j = 0; j < 4; j++)
{
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
}
}
return output;
}
/*
* Convert a raw string to an arbitrary string encoding
*/
function rstr2any(input, encoding)
{
var divisor = encoding.length;
var i, j, q, x, quotient;
/* Convert to an array of 16-bit big-endian values, forming the dividend */
var dividend = Array(Math.ceil(input.length / 2));
for(i = 0; i < dividend.length; i++)
{
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
}
/*
* Repeatedly perform a long division. The binary array forms the dividend,
* the length of the encoding is the divisor. Once computed, the quotient
* forms the dividend for the next step. All remainders are stored for later
* use.
*/
var full_length = Math.ceil(input.length * 8 /
(Math.log(encoding.length) / Math.log(2)));
var remainders = Array(full_length);
for(j = 0; j < full_length; j++)
{
quotient = Array();
x = 0;
for(i = 0; i < dividend.length; i++)
{
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if(quotient.length > 0 || q > 0)
quotient[quotient.length] = q;
}
remainders[j] = x;
dividend = quotient;
}
/* Convert the remainders to the output string */
var output = "";
for(i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
return output;
}
/*
* Encode a string as utf-8.
* For efficiency, this assumes the input is valid utf-16.
*/
function str2rstr_utf8(input)
{
var output = "";
var i = -1;
var x, y;
while(++i < input.length)
{
/* Decode utf-16 surrogate pairs */
x = input.charCodeAt(i);
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
{
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
/* Encode output as utf-8 */
if(x <= 0x7F)
output += String.fromCharCode(x);
else if(x <= 0x7FF)
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
0x80 | ( x & 0x3F));
else if(x <= 0xFFFF)
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
else if(x <= 0x1FFFFF)
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
}
return output;
}
/*
* Encode a string as utf-16
*/
function str2rstr_utf16le(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF);
return output;
}
function str2rstr_utf16be(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
input.charCodeAt(i) & 0xFF);
return output;
}
/*
* Convert a raw string to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
function rstr2binl(input)
{
var output = Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;
for(var i = 0; i < input.length * 8; i += 8)
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
return output;
}
/*
* Convert an array of little-endian words to a string
*/
function binl2rstr(input)
{
var output = "";
for(var i = 0; i < input.length * 32; i += 8)
output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
return output;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function binl_md5(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t)
{
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment