TinyChan

New reply in topic: Random discussions thread

You are not recognized as the original poster of this topic.

:

You are required to fill in a captcha for your first 5 posts. Sorry, but this is required to stop people from posting while drunk. Please be responsible and don't drink and post!
If you receive this often, consider not clearing your cookies.

Please familiarise yourself with the rules and markup syntax before posting.


Replying to Phoneposter…

@659,039
Least intuitive solution award…
function baseNEncode(bytes,alphabet){
  const n=BigInt(alphabet.length);
  let num=BigInt(0);
  //Convert bytes to a BigInt.
  for(let i=0;i<bytes.length;i++){
    num=(num<<8n)+BigInt(bytes[i]);
  }
  let result="";
  if(num===0n){ //Special case for zero value.
    result=alphabet[0];
  }else{
    //Convert the BigInt to base-N string.
    while(num>0n){
      const rem=num%n;
      num/=n;
      result=alphabet[Number(rem)]+result;
    }
  }
  //Preserve leading zero bytes.
  let zeros=0;
  for(let i=0;i<bytes.length&&bytes[i]===0;i++)zeros++;
  //Add leading zeros as the first character in the alphabet.
  result=alphabet[0].repeat(zeros)+result;
  return result;
}
function baseNDecode(str,alphabet){
  const n=BigInt(alphabet.length),
        baseMap=new Map();
  //Create a mapping from characters to their numeric values.
  for(let i=0;i<alphabet.length;i++)
    baseMap.set(alphabet[i], BigInt(i));
  //Count leading characters corresponding to zero bytes.
  let zeros=0;
  for(let i=0;i<str.length&&str[i]===alphabet[0];i++)zeros++;
  //Convert the string back to a BigInt.
  let num=BigInt(0);
  for(let i=zeros;i<str.length;i++)
    num=num*n+baseMap.get(str[i]);
  //Convert the BigInt back to bytes.
  let bytes=[];
  while(num>0n){
    bytes.unshift(Number(num&0xFFn));
    num=num>>8n;
  }
  //Prepend the leading zero bytes.
  const leadingZeros=new Uint8Array(zeros);
  return Uint8Array.from([...leadingZeros,...bytes]);
}

strRange=(a,b)=>Array.from({length:(b.charCodeAt(0)-a.charCodeAt(0))+1},(_,i)=>String.fromCharCode(a.charCodeAt(0)+i)).join("");
base128Alphabet=strRange("0","9")+strRange("A","Z")+strRange("a","z")+strRange("À","ÿ")+"+/"; //0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ+/

function randomU8array(len){let array=new Uint8Array(len);for(let i=0;i<array.length;i++)array[i]=Math.floor(Math.random()*256);return array;}

function arraysEqual(a,b){
  if(a===b)return true;
  if(a.length!==b.length)return false;
  for(let i=0;i<a.length;i++)
    if(a[i]!==b[i])return false;
  return true;
}

for(let i=0;i<10;i++){
  let randomBytes=randomU8array(10+Math.random()*100),
      encoded=baseNEncode(randomBytes,base128Alphabet),
      decoded=baseNDecode(encoded,base128Alphabet);
  console.log([...randomBytes].map(x=>x.toString(16).padStart(2,"0")));
  console.log(encoded);
  console.log([...decoded].map(x=>x.toString(16).padStart(2,"0")));
  console.log(arraysEqual(randomBytes,decoded));
}