Check out Sunborn's two newly announced games (official English titles pending): Girls' Frontline: Blue Butterfly Contract and Reverse Collapse: F !
You don't need an account to join in. Learn how to contribute, browse Bounties and join our Discord server.

MediaWiki:Gadget-md5hasher.js: Difference between revisions

Welcome to IOP Wiki. This website is maintained by the Girls' Frontline community and is free to edit by anyone.
Jump to navigation Jump to search
Adding ICSGenerator to the tooling framework
m Small typo
Line 183: Line 183:
var container = document.currentScript.parentNode;
var container = document.currentScript.parentNode;
container.appendChild(icsLink);
container.appendChild(icsLink);
}
};

Revision as of 19:09, 18 July 2025

window.gfUtils = window.gfUtils || {};

(function(globSpace){'use strict';function safe_add(x,y){var lsw=(x&0xFFFF)+(y&0xFFFF),msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xFFFF)}
function bit_rol(num,cnt){return(num<<cnt)|(num>>>(32-cnt))}
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)}
function binl_md5(x,len){x[len>>5]|=0x80<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var i,olda,oldb,oldc,oldd,a=1732584193,b=-271733879,c=-1732584194,d=271733878;for(i=0;i<x.length;i+=16){olda=a;oldb=b;oldc=c;oldd=d;a=md5_ff(a,b,c,d,x[i],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],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],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],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[a,b,c,d]}
function binl2rstr(input){var i,output='';for(i=0;i<input.length*32;i+=8){output+=String.fromCharCode((input[i>>5]>>>(i%32))&0xFF)}
return output}
function rstr2binl(input){var i,output=[];output[(input.length>>2)-1]=undefined;for(i=0;i<output.length;i+=1){output[i]=0}
for(i=0;i<input.length*8;i+=8){output[i>>5]|=(input.charCodeAt(i/8)&0xFF)<<(i%32)}
return output}
function rstr_md5(s){return binl2rstr(binl_md5(rstr2binl(s),s.length*8))}
function rstr_hmac_md5(key,data){var i,bkey=rstr2binl(key),ipad=[],opad=[],hash;ipad[15]=opad[15]=undefined;if(bkey.length>16){bkey=binl_md5(bkey,key.length*8)}
for(i=0;i<16;i+=1){ipad[i]=bkey[i]^0x36363636;opad[i]=bkey[i]^0x5C5C5C5C}
hash=binl_md5(ipad.concat(rstr2binl(data)),512+data.length*8);return binl2rstr(binl_md5(opad.concat(hash),512+128))}
function rstr2hex(input){var hex_tab='0123456789abcdef',output='',x,i;for(i=0;i<input.length;i+=1){x=input.charCodeAt(i);output+=hex_tab.charAt((x>>>4)&0x0F)+hex_tab.charAt(x&0x0F)}
return output}
function str2rstr_utf8(input){return unescape(encodeURIComponent(input))}
function raw_md5(s){return rstr_md5(str2rstr_utf8(s))}
function hex_md5(s){return rstr2hex(raw_md5(s))}
function raw_hmac_md5(k,d){return rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d))}
function hex_hmac_md5(k,d){return rstr2hex(raw_hmac_md5(k,d))}
globSpace.md5=function(string,key,raw){if(!key){if(!raw){return hex_md5(string)}else{return raw_md5(string)}}
if(!raw){return hex_hmac_md5(key,string)}else{return raw_hmac_md5(key,string)}}}(window.gfUtils))

window.gfUtils.createWikiPathPart = function createPathPart(filename) {
  var hash = window.gfUtils.md5(decodeURIComponent(filename));
  return hash[0] + "/" + hash[0] + hash[1] + "/";
};

var createSliderButtonCounter = 0;
window.gfUtils.createSliderButton = function createSliderButton(iconUrl, eventHandler) {


  var idForThisButton = "dormSliderIdent" + createSliderButtonCounter;
  createSliderButtonCounter = createSliderButtonCounter + 1;

  var dormInput = $('<input></input>');
  dormInput.attr('type', "checkbox");
  dormInput.attr('value', "None");
  dormInput.attr('name', "check");
  dormInput.attr('id', idForThisButton);
  dormInput.change(eventHandler);
                
  var dormSpanOn = $('<span></span >');
  dormSpanOn.addClass('texton');
  dormSpanOn.text('ON');
                
  var dormLabel = $('<label></label>');
  dormLabel.attr('for', idForThisButton);
                
  var dormSpanOff = $('<span></span >');
  dormSpanOff.addClass('textoff');
  dormSpanOff.text('OFF');
                
  var dormSlidebutton = $('<div></div>');
  dormSlidebutton.addClass('slideButton');
  dormSlidebutton.append(dormSpanOn);
  dormSlidebutton.append(dormLabel);
  dormSlidebutton.append(dormSpanOff);
                
  var dormSwitcher = $('<div></div>');
  dormSwitcher.addClass('chibiDormSwitcher');
  dormSwitcher.append(dormInput);
  dormSwitcher.append(dormSlidebutton);
  
  return dormSwitcher;
};

window.gfUtils.base64ArrayBuffer = function base64ArrayBuffer(arrayBuffer) {
  var base64    = '';
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  var bytes         = new Uint8Array(arrayBuffer);
  var byteLength    = bytes.byteLength;
  var byteRemainder = byteLength % 3;
  var mainLength    = byteLength - byteRemainder;

  var a, b, c, d;
  var chunk;

  var i;
  // Main loop deals with bytes in chunks of 3
  for (i = 0; i < mainLength; i = i + 3) {
    // Combine the three bytes into a single integer
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];

    // Use bitmasks to extract 6-bit segments from the triplet
    a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18;
    b = (chunk & 258048)   >> 12; // 258048   = (2^6 - 1) << 12;
    c = (chunk & 4032)     >>  6; // 4032     = (2^6 - 1) << 6;
    d = chunk & 63              ; // 63       = 2^6 - 1;

    // Convert the raw binary segments to the appropriate ASCII encoding
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
  }

  // Deal with the remaining bytes and padding
  if (byteRemainder == 1) {
    chunk = bytes[mainLength];

    a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2;

    // Set the 4 least significant bits to zero
    b = (chunk & 3)   << 4; // 3   = 2^2 - 1;

    base64 += encodings[a] + encodings[b] + '==';
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];

    a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10;
    b = (chunk & 1008)  >>  4; // 1008  = (2^6 - 1) << 4;

    // Set the 2 least significant bits to zero
    c = (chunk & 15)    <<  2; // 15    = 2^4 - 1;

    base64 += encodings[a] + encodings[b] + encodings[c] + '=';
  }

  return base64;
};

/* =========== Widget functions */

/* ----------- ICSGenerator*/

/* Hashing as seen on https://stackoverflow.com/a/52171480 */
window.iopwidgets = window.iopwidgets || {};
window.iopwidgets.ICSGenerator = window.iopwidgets.ICSGenerator || {};
window.iopwidgets.ICSGenerator.cyrb53 = function(str, seedRaw) {
    var seed = seedRaw || 0;
    var h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
    for (var i = 0, ch; i < str.length; i++) {
        ch = str.charCodeAt(i);
        h1 = Math.imul(h1 ^ ch, 2654435761);
        h2 = Math.imul(h2 ^ ch, 1597334677);
    }
    h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
    h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
    return 4294967296 * (2097151 & h2) + (h1>>>0);
};

window.iopwidgets.ICSGenerator.buildIcsLink = function(name, start, end) {
	var d= new Date();
	var currentDateString = d.getFullYear() + ("0"+(d.getMonth()+1)).slice(-2) + ("0" + d.getDate()).slice(-2) + "T"
	 + ("0" + d.getHours()).slice(-2) + ("0" + d.getMinutes()).slice(-2) + ("0" + d.getSeconds()).slice(-2);

	var hash = cyrb53("" + name + start + end);

	var icsContent = "BEGIN:VCALENDAR\r\n";
	icsContent += "VERSION:2.0\r\n";
	icsContent += "PRODID:-//iopwiki.com//ICS Widget\r\n";
	icsContent += "CALSCALE:GREGORIAN\r\n";
	icsContent += "BEGIN:VEVENT\r\n";
	icsContent += "DTSTAMP:" + currentDateString + "\r\n";
	icsContent += "UID:" + hash + "\r\n";
	icsContent += "DTSTART;TZID=Etc/UTC:" + start + "\r\n";
	icsContent += "DTEND;TZID=Etc/UTC:" + end + "\r\n";
	icsContent += "SUMMARY:" + name + "\r\n";
	icsContent += "END:VEVENT\r\n";
	icsContent += "END:VCALENDAR\r\n";
	
	var icsLink = document.createElement("a");
	icsLink.classList.add('ics-link');
	icsLink.setAttribute("href", "javascript:void(0);");
	icsLink.setAttribute("target", "_blank");
	icsLink.setAttribute("rel", "noopener");
	icsLink.setAttribute("tooltip", "Download iCal file");
	icsLink.setAttribute("download", "event.ics");
	icsLink.addEventListener('click', function(e) {
		var uriContent = "data:text/calendar," + encodeURIComponent(icsContent);
		e.target.href = uriContent;
	});
	
	var visibleText = document.createTextNode("Download iCal file");
	icsLink.appendChild(visibleText);
	
	var container = document.currentScript.parentNode;
	container.appendChild(icsLink);
};