Skip to content

Instantly share code, notes, and snippets.

@Bloodwyn
Last active January 6, 2023 21:03
Show Gist options
  • Select an option

  • Save Bloodwyn/ff8fd940f064fd321757468b47c5a5ba to your computer and use it in GitHub Desktop.

Select an option

Save Bloodwyn/ff8fd940f064fd321757468b47c5a5ba to your computer and use it in GitHub Desktop.

Revisions

  1. Bloodwyn revised this gist Apr 23, 2020. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion md5.sqf
    Original file line number Diff line number Diff line change
    @@ -116,7 +116,6 @@ BW_hash_fnc_or32 = {
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    diag_log str _a;
    [
    [_a#0,_b#0] call BIS_fnc_bitwiseOR,
    [_a#1,_b#1] call BIS_fnc_bitwiseOR,
  2. Bloodwyn revised this gist Apr 23, 2020. 1 changed file with 12 additions and 14 deletions.
    26 changes: 12 additions & 14 deletions md5.sqf
    Original file line number Diff line number Diff line change
    @@ -62,11 +62,11 @@ BW_hash_fnc_shiftr32 = {
    _maskForOverflow = 2^_c-1;

    _a0 = [_a#0,_c] call BW_hash_fnc_shiftr;
    _r = [[_a#0,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _r = [[_a#0,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftl;
    _a1 = [[_a#1,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#1,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _r = [[_a#1,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftl;
    _a2 = [[_a#2,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#2,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _r = [[_a#2,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftl;
    _a3 = [[_a#3,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    [_a0,_a1,_a2,_a3];
    };
    @@ -88,13 +88,13 @@ BW_hash_fnc_shiftl32 = {

    _maskForOverflow = [[2^(8-_c)-1] call BIS_fnc_bitwiseNOT,0xFF] call BIS_fnc_bitwiseAND;

    _a3 = [_a#3,_c] call shiftl;
    _a3 = [_a#3,_c] call BW_hash_fnc_shiftl;
    _r = [[_a#3,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a2 = [[_a#2,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    _a2 = [[_a#2,_c] call BW_hash_fnc_shiftl,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#2,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a1 = [[_a#1,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    _a1 = [[_a#1,_c] call BW_hash_fnc_shiftl,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#1,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a0 = [[_a#0,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    _a0 = [[_a#0,_c] call BW_hash_fnc_shiftl,_r] call BIS_fnc_bitwiseOR;
    [_a0 mod 256,_a1 mod 256,_a2 mod 256,_a3 mod 256];
    };

    @@ -116,6 +116,7 @@ BW_hash_fnc_or32 = {
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    diag_log str _a;
    [
    [_a#0,_b#0] call BIS_fnc_bitwiseOR,
    [_a#1,_b#1] call BIS_fnc_bitwiseOR,
    @@ -164,9 +165,6 @@ BW_hash_fnc_add32 = {
    [_v4 mod 256,_v3 mod 256,_v2 mod 256,_v1 mod 256];
    };

    [[255,0,0,0],[1,0,0,0]] call BW_hash_fnc_add32;


    BW_hash_fnc_decStrMod = {
    private _str = param [0,"",[""]];
    private ["_r","_e"];
    @@ -211,20 +209,20 @@ BW_hash_fnc_fromHexStr = {
    _tn0 = if(_x >= 96)then{_x-87}else{_x-48};
    }else{
    _tn1 = if(_x >= 96)then{_x-87}else{_x-48};
    _num pushBack (([_tn0,4] call shiftl) + _tn1);
    _num pushBack (([_tn0,4] call BW_hash_fnc_shiftl) + _tn1);
    _flag = true;
    };
    };
    if(!_flag)then{
    _num pushBack([_tn0,4] call shiftl);
    _num pushBack([_tn0,4] call BW_hash_fnc_shiftl);
    };
    _num;
    };

    BW_hash_fnc_toHexStr = {
    if(typeName _this isEqualTo "ARRAY")exitWith{
    _str = "";
    _this apply {_str = _str + (_x call toHexStr)};
    _this apply {_str = _str + (_x call BW_hash_fnc_toHexStr)};
    _str;
    };
    _lkup = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
    @@ -346,7 +344,7 @@ BW_hash_fnc_md5 = {

    _toshift = [[[_a, _f] call BW_hash_fnc_add32,_k#_i] call BW_hash_fnc_add32,[_msg # (_selfrom+3), _msg # (_selfrom+2), _msg # (_selfrom+1), _msg # _selfrom]] call BW_hash_fnc_add32;

    _b = [_b,[[_toshift,_shift] call shiftl32,[_toshift,32 - _shift] call BW_hash_fnc_shiftr32] call BW_hash_fnc_or32] call BW_hash_fnc_add32;
    _b = [_b,[[_toshift,_shift] call BW_hash_fnc_shiftl32,[_toshift,32 - _shift] call BW_hash_fnc_shiftr32] call BW_hash_fnc_or32] call BW_hash_fnc_add32;
    _a = _temp;
    };
    _h0 = [_h0,_a] call BW_hash_fnc_add32;
  3. Bloodwyn revised this gist Jan 6, 2020. No changes.
  4. Bloodwyn revised this gist Jan 6, 2020. No changes.
  5. Bloodwyn created this gist Jan 6, 2020.
    368 changes: 368 additions & 0 deletions md5.sqf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,368 @@
    /*
    Implementaion of the md5 hashing algorithm in sqf
    en.wikipedia.org/wiki/md5
    community.bistudio.com/wiki/SQF_syntax
    Author: Bastian Kuth | "Bloodwyn"
    Its rather slow (about 120ms per GUID), but can be used to convert the SteamID64 to the BattleEye GUID without having to use external tools or addons.
    developer.valvesoftware.com/wiki/SteamID
    The main challenge developing this was the lack of an Integer datatype in sqf.
    I used this C implementaion from Tim Caswell as a reference: gist.github.com/creationix/4710780
    */

    BW_hash_fnc_calloc = {
    private _ret = [];
    _ret set [_this-1,0];
    _ret apply {0};
    };

    BW_hash_fnc_memcpy = {
    params ["_dst", "_src", "_len"];
    for "_i" from 0 to (_len-1) step 1 do {
    _dst set [_i,_src # _i];
    };
    _dst;
    };

    BW_hash_fnc_shiftr = {
    params [
    ["_a",0,[0]],
    ["_c",0,[0]]
    ];
    floor (_a / (2 ^ _c));
    };

    BW_hash_fnc_shiftl = {
    params [
    ["_a",0,[0]],
    ["_c",0,[0]]
    ];
    (_a * (2 ^ _c)) mod 256;
    };

    BW_hash_fnc_shiftr32 = {
    params [
    ["_a",[],[[]],4],
    ["_c",0,[0]]
    ];
    _a = +_a;

    private ["_r","_a0","_a1","_a2","_a3","_maskForOverflow"];

    while {_c>8} do {
    _c = _c-8;
    _a deleteAt 3;
    _a = [0] + _a;
    };

    _maskForOverflow = 2^_c-1;

    _a0 = [_a#0,_c] call BW_hash_fnc_shiftr;
    _r = [[_a#0,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _a1 = [[_a#1,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#1,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _a2 = [[_a#2,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#2,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call shiftl;
    _a3 = [[_a#3,_c] call BW_hash_fnc_shiftr,_r] call BIS_fnc_bitwiseOR;
    [_a0,_a1,_a2,_a3];
    };

    BW_hash_fnc_shiftl32 = {
    params [
    ["_a",[],[[]],4],
    ["_c",0,[0]]
    ];
    _a = +_a;

    private ["_r","_a0","_a1","_a2","_a3","_maskForOverflow"];

    while {_c>8} do {
    _c = _c-8;
    _a deleteAt 0;
    _a pushBack 0;
    };

    _maskForOverflow = [[2^(8-_c)-1] call BIS_fnc_bitwiseNOT,0xFF] call BIS_fnc_bitwiseAND;

    _a3 = [_a#3,_c] call shiftl;
    _r = [[_a#3,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a2 = [[_a#2,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#2,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a1 = [[_a#1,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    _r = [[_a#1,_maskForOverflow] call BIS_fnc_bitwiseAND, 8-_c] call BW_hash_fnc_shiftr;
    _a0 = [[_a#0,_c] call shiftl,_r] call BIS_fnc_bitwiseOR;
    [_a0 mod 256,_a1 mod 256,_a2 mod 256,_a3 mod 256];
    };

    BW_hash_fnc_and32 = {
    params [
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    [
    [_a#0,_b#0] call BIS_fnc_bitwiseAND,
    [_a#1,_b#1] call BIS_fnc_bitwiseAND,
    [_a#2,_b#2] call BIS_fnc_bitwiseAND,
    [_a#3,_b#3] call BIS_fnc_bitwiseAND
    ];
    };

    BW_hash_fnc_or32 = {
    params [
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    [
    [_a#0,_b#0] call BIS_fnc_bitwiseOR,
    [_a#1,_b#1] call BIS_fnc_bitwiseOR,
    [_a#2,_b#2] call BIS_fnc_bitwiseOR,
    [_a#3,_b#3] call BIS_fnc_bitwiseOR
    ];
    };

    BW_hash_fnc_xor32 = {
    params [
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    [
    ([_a#0,_b#0] call BIS_fnc_bitwiseXOR) mod 256,
    ([_a#1,_b#1] call BIS_fnc_bitwiseXOR) mod 256,
    ([_a#2,_b#2] call BIS_fnc_bitwiseXOR) mod 256,
    ([_a#3,_b#3] call BIS_fnc_bitwiseXOR) mod 256
    ];
    };

    BW_hash_fnc_not32 = {
    private _a = _this;
    [
    ((_a#0) call BIS_fnc_bitwiseNOT) mod 256,
    ((_a#1) call BIS_fnc_bitwiseNOT) mod 256,
    ((_a#2) call BIS_fnc_bitwiseNOT) mod 256,
    ((_a#3) call BIS_fnc_bitwiseNOT) mod 256
    ];
    };

    BW_hash_fnc_add32 = {
    params [
    ["_a",[],[[]],4],
    ["_b",[],[[]],4]
    ];
    private ["_v1","_v2","_v3","_v4","_o"];
    _v1 = (_a#3)+(_b#3);
    _o = floor (_v1 / 256);
    _v2 = (_a#2)+(_b#2)+_o;
    _o = floor (_v2 / 256);
    _v3 = (_a#1)+(_b#1)+_o;
    _o = floor (_v3 / 256);
    _v4 = (_a#0)+(_b#0)+_o;
    _o = floor (_v3 / 256);
    [_v4 mod 256,_v3 mod 256,_v2 mod 256,_v1 mod 256];
    };

    [[255,0,0,0],[1,0,0,0]] call BW_hash_fnc_add32;


    BW_hash_fnc_decStrMod = {
    private _str = param [0,"",[""]];
    private ["_r","_e"];
    _e = "";
    _parsed = parseNumber _str;
    if(count _str < 3 or (_parsed < 256))exitWith{
    [str (floor (_parsed / 256)),_parsed % 256];
    };
    _part = parseNumber (_str select [0,3]);
    for "_i" from 3 to ((count _str)) step 1 do {
    _r = _part % 256;
    _e = _e + str floor (_part / 256);
    _part = _r*10 + parseNumber (_str select [_i,1]);
    };
    [_e,_r];
    };

    BW_hash_fnc_fromDecStr = {
    private _str = param [0,"",[""]];

    _bytes = [];
    while{!(_str isEqualTo "0")} do {
    _ret = _str call BW_hash_fnc_decStrMod;
    _str = _ret#0;
    _bytes = [_ret#1] + _bytes;
    };

    _bytes;
    };

    BW_hash_fnc_fromHexStr = {
    private ["_str","_num","_flag","_tn0","_tn1"];
    _str = toLower _this;
    if(_str select [0,2] isEqualTo "0x")then{_str = _str select [2,1e6]};

    if((count _str) mod 2 isEqualTo 1)then{_str = "0"+_str};
    _num = [];
    _flag = true;
    (toArray _str) apply {
    if(_flag)then{
    _flag = false;
    _tn0 = if(_x >= 96)then{_x-87}else{_x-48};
    }else{
    _tn1 = if(_x >= 96)then{_x-87}else{_x-48};
    _num pushBack (([_tn0,4] call shiftl) + _tn1);
    _flag = true;
    };
    };
    if(!_flag)then{
    _num pushBack([_tn0,4] call shiftl);
    };
    _num;
    };

    BW_hash_fnc_toHexStr = {
    if(typeName _this isEqualTo "ARRAY")exitWith{
    _str = "";
    _this apply {_str = _str + (_x call toHexStr)};
    _str;
    };
    _lkup = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
    (_lkup # (floor (_this / 16))) + (_lkup # (_this mod 16));
    };

    BW_hash_fnc_toNum = {
    _num = 0;
    _this apply {_num = _num*256 + _x};
    _num;
    };

    BW_hash_fnc_hashToString = {
    _ui32ar = _this;
    _str = "";
    _ui32ar apply {
    _bytes = _x;
    _istr = "";
    _bytes apply {
    _istr = (_x call BW_hash_fnc_toHexStr) + _istr;
    };
    _str = _str + _istr;
    };
    _str
    };

    BW_hash_fnc_md5 = {
    private ["_r","_k","_ho","_h1","_h2","_h3","_initial_msg","_initial_len","_new_len","_msg","_bits_len","_a","_b","_c","_d","_f","_g","_temp","_shift","_toshift","_selfrom"];
    _r = [ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
    5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
    4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
    6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21];
    _k = [
    [0xd7,0x6a,0xa4,0x78], [0xe8,0xc7,0xb7,0x56], [0x24,0x20,0x70,0xdb], [0xc1,0xbd,0xce,0xee],
    [0xf5,0x7c,0x0f,0xaf], [0x47,0x87,0xc6,0x2a], [0xa8,0x30,0x46,0x13], [0xfd,0x46,0x95,0x01],
    [0x69,0x80,0x98,0xd8], [0x8b,0x44,0xf7,0xaf], [0xff,0xff,0x5b,0xb1], [0x89,0x5c,0xd7,0xbe],
    [0x6b,0x90,0x11,0x22], [0xfd,0x98,0x71,0x93], [0xa6,0x79,0x43,0x8e], [0x49,0xb4,0x08,0x21],
    [0xf6,0x1e,0x25,0x62], [0xc0,0x40,0xb3,0x40], [0x26,0x5e,0x5a,0x51], [0xe9,0xb6,0xc7,0xaa],
    [0xd6,0x2f,0x10,0x5d], [0x02,0x44,0x14,0x53], [0xd8,0xa1,0xe6,0x81], [0xe7,0xd3,0xfb,0xc8],
    [0x21,0xe1,0xcd,0xe6], [0xc3,0x37,0x07,0xd6], [0xf4,0xd5,0x0d,0x87], [0x45,0x5a,0x14,0xed],
    [0xa9,0xe3,0xe9,0x05], [0xfc,0xef,0xa3,0xf8], [0x67,0x6f,0x02,0xd9], [0x8d,0x2a,0x4c,0x8a],
    [0xff,0xfa,0x39,0x42], [0x87,0x71,0xf6,0x81], [0x6d,0x9d,0x61,0x22], [0xfd,0xe5,0x38,0x0c],
    [0xa4,0xbe,0xea,0x44], [0x4b,0xde,0xcf,0xa9], [0xf6,0xbb,0x4b,0x60], [0xbe,0xbf,0xbc,0x70],
    [0x28,0x9b,0x7e,0xc6], [0xea,0xa1,0x27,0xfa], [0xd4,0xef,0x30,0x85], [0x04,0x88,0x1d,0x05],
    [0xd9,0xd4,0xd0,0x39], [0xe6,0xdb,0x99,0xe5], [0x1f,0xa2,0x7c,0xf8], [0xc4,0xac,0x56,0x65],
    [0xf4,0x29,0x22,0x44], [0x43,0x2a,0xff,0x97], [0xab,0x94,0x23,0xa7], [0xfc,0x93,0xa0,0x39],
    [0x65,0x5b,0x59,0xc3], [0x8f,0x0c,0xcc,0x92], [0xff,0xef,0xf4,0x7d], [0x85,0x84,0x5d,0xd1],
    [0x6f,0xa8,0x7e,0x4f], [0xfe,0x2c,0xe6,0xe0], [0xa3,0x01,0x43,0x14], [0x4e,0x08,0x11,0xa1],
    [0xf7,0x53,0x7e,0x82], [0xbd,0x3a,0xf2,0x35], [0x2a,0xd7,0xd2,0xbb], [0xeb,0x86,0xd3,0x91]
    ];

    _h0 = [0x67,0x45,0x23,0x01];
    _h1 = [0xef,0xcd,0xab,0x89];
    _h2 = [0x98,0xba,0xdc,0xfe];
    _h3 = [0x10,0x32,0x54,0x76];

    _initial_msg = _this;

    if(typeName _this isEqualTo "STRING")then{
    _initial_msg = (toArray _initial_msg);
    };

    _initial_len = (count _initial_msg);

    _new_len = ((floor ((_initial_len + 8) / 64) + 1) * 64) - 8;

    _msg = (_new_len + 64) call BW_hash_fnc_calloc;
    _msg = [_msg, _initial_msg, _initial_len] call BW_hash_fnc_memcpy;

    _msg set [_initial_len,128];


    _bits_len = 8 * _initial_len;

    _msg set [_new_len+3 ,floor (_bits_len / (2^24)) mod 256];
    _msg set [_new_len+2,floor (_bits_len / (2^16)) mod 256];
    _msg set [_new_len+1,floor (_bits_len / (2^8)) mod 256];
    _msg set [_new_len+0,floor (_bits_len) mod 256];

    for "_offset" from 0 to (_new_len-1) step (512 / 8) do {
    _a = _h0;
    _b = _h1;
    _c = _h2;
    _d = _h3;

    for "_i" from 0 to (64-1) step 1 do {
    switch (true) do {
    case (_i < 16) : {
    _f = [
    [_b,_c] call BW_hash_fnc_and32,
    [_b call BW_hash_fnc_not32,_d] call BW_hash_fnc_and32
    ] call BW_hash_fnc_or32;
    _g = [0,0,0,_i];
    };
    case (_i < 32) : {
    _f = [
    [_d,_b] call BW_hash_fnc_and32,
    [_d call BW_hash_fnc_not32,_c] call BW_hash_fnc_and32
    ] call BW_hash_fnc_or32;
    _g = [0,0,0,(5 * _i + 1) % 16];
    };
    case (_i < 48) : {
    _f = [[_b,_c] call BW_hash_fnc_xor32,_d] call BW_hash_fnc_xor32;
    _g = [0,0,0,(3 * _i + 5) % 16];
    };
    default {
    _f = [_c,[_b,_d call BW_hash_fnc_not32] call BW_hash_fnc_or32] call BW_hash_fnc_xor32;
    _g = [0,0,0,(7 * _i) % 16];
    };
    };

    _temp = _d;
    _d = _c;
    _c = _b;

    _shift = _r#_i;

    _selfrom = _offset + ((_g call BW_hash_fnc_toNum)*4);

    _toshift = [[[_a, _f] call BW_hash_fnc_add32,_k#_i] call BW_hash_fnc_add32,[_msg # (_selfrom+3), _msg # (_selfrom+2), _msg # (_selfrom+1), _msg # _selfrom]] call BW_hash_fnc_add32;

    _b = [_b,[[_toshift,_shift] call shiftl32,[_toshift,32 - _shift] call BW_hash_fnc_shiftr32] call BW_hash_fnc_or32] call BW_hash_fnc_add32;
    _a = _temp;
    };
    _h0 = [_h0,_a] call BW_hash_fnc_add32;
    _h1 = [_h1,_b] call BW_hash_fnc_add32;
    _h2 = [_h2,_c] call BW_hash_fnc_add32;
    _h3 = [_h3,_d] call BW_hash_fnc_add32;
    };
    [_h0,_h1,_h2,_h3] call BW_hash_fnc_hashToString;
    };

    BW_hash_fnc_steamIdToGUID = {
    private _steamid = param [0, "",[""]];
    private _bytes = _steamid call BW_hash_fnc_fromDecStr;
    reverse _bytes;
    _tohash = (toArray "BE") + _bytes;
    ((toArray "BE") + _bytes) call BW_hash_fnc_md5;
    };

    ["76561198055205907"] call BW_hash_fnc_steamidToGUID; // returns "861211889e6b3e4c3a584c5d42cb4825"