# Introduction

File names can be wildly varying things, ranging from a simple blah.txt to 303549020150514101638190-MSP0.txt. The former is usually human generated, while the latter is often machine generated. Wouldn't it be nice to have a simple function to make educated guesses on whether or not a file might be considered "human-friendly"?

Inspired by a post by Eduard Florinescu that has since been deleted. His idea was good, but just needed a little fleshing out.

# Challenge

Write a program or function in the language of your choice that can take an string, and determine if it is considered "human-friendly", as defined by this challenge.

Some further details and rules are as follows:

• Input will be a string consisting of the 95 printable ascii characters.
• "human-friendly" shall be defined thusly:
• Exclude the extension in the consideration. An extension is defined as the final period followed by a series of alpha-numeric characters (as few as 1, as many as 6).
• No more than half of the string by length (excluding extension) may consist of the following defined groupings of characters (combined):
• Decimal characters longer than 8 in a row.
• Hexadecimal characters (upper xor lower case) of at least 16 in a row (must consist of letters and numbers, and of which at least a third of the characters are numbers).
• Base64 characters (using %+= as the special characters) of at least 12 in a row (must consist of letters and numbers, be mixed case, and of which at least a third of the characters are uppercase letters).
• If any of the above groupings overlap in definition (such as one that qualifies as base64, but has 8 digits in a row), choose the longest of them to be excluded.
• Output should be a truthy or falsy value, depending on if the string is considered "human-friendly" or not.
• Assume that only valid input will be used. Don't worry about error handling.

The winner will be determined by the shortest program/function. They will be selected in at least 7 days, or if/when there have been enough submissions. In the event of a tie, the answer that came earlier wins.

# Examples

Here's a few examples of input and output that your code should be able to handle:

"results_for__michael_greer.txt.zip" => true

"Georg Feuerstein - Connecting the Dots.pdf" => true

"M People - Search for the Hero-ntuqTuc6HxM.mp4" => true

"index.html?v=QTR4WGVTUzFsV3d8NHxvcmlnaW5hbHx8MTExMTAxBHxodHRwOi8vLCwsLHRyLDcsMA%3D%3D.html" => false

"ol2DCE0SIyQC(173).pdf" => false

"d41d8cd98f00b204e9800998ecf8427e.md5" => false

"12792331_807918856008495_7076645197310150318_o.jpg" => false


# Javascript, 466 bytes

s=>(s=s.split(/\.[a-z\d]{1,6}$/i)[j=d=0],h=s[l='length']/2|0,m=[],g=r=>(++j,m=m.concat((s[n='match'](r)||[]).map(x=>[x,j]))),p='replace',g(/\d{9,}/g),g(/[\da-f]{16,}/ig),g(/[\da-z%+=]{12,}/ig),m.sort((x,y)=>y[0][l]-x[0][l]).every(x=>x[1]-1?x[1]-2?s=s[p](x[0],y=>y[n](/[a-z]/)&&y[n](/\d/)&&(y+'A')[n](/[A-Z]/g)[l]>y[l]/3|0?(d+=y[l],''):y):s=s[p](x[0],y=>!!y[n](/[A-F]/)^!!y[n](/[a-f]/)&&(y+'0')[n](/\d/g)[l]>y[l]/3|0?(d+=y[l],''):y):(s=s[p](z=x[0],''),d+=z[l])),d<=h)  Explaining: f=s=>( // f: take string s (filename) as input s=s.split(/\.[a-z\d]{1,6}$/i)[j=d=0],  // s: input without extension
// d: combined rules' sum
// j: combined rule-number step
h=s[l='length']/2|0,                   // h: half string
// l: length
m=[],                                  // m: matches
g=r=>(++j,                             // j: next combined rule number
m=m.concat(                            // m: join
(s[n='match'](r)||[]).map(             // new (r)egex-matches
x=>[x,j])                              // mapped with its rule number
)),p='replace',                        // p: replace
g(/\d{9,}/g),                          // combined rules §1
g(/[\da-f]{16,}/ig),                   // combined rules §2
g(/[\da-z%+=]{12,}/ig),                // combined rules \$3
m.sort((x,y)=>y[0][l]-x[0][l])         // matches ordered by length
.every(x=>x[1]-1?                      // for combined rule §1
x[1]-2?                                // for combined rule §2
s=s[p](x[0],y=>                        // for combined rule §3
y[n](/[a-z]/)&&y[n](/\d/)&&            // if lower and digit and
(y+'A')[n](/[A-Z]/g)[l]>y[l]/3|0?      // upper at least total/3
(d+=y[l],''):y)                        // replace by empty and sum up d
:s=s[p](x[0],y=>                       // replace if
!!y[n](/[A-F]/)^!!y[n](/[a-f]/)&&      // (upper xor lower case) and
(y+'0')[n](/\d/g)[l]>y[l]/3|0?         // digits: at least total/3
(d+=y[l],''):y)                        // by empty and sum up d
:(s=s[p](z=x[0],''),d+=z[l]))          // no treatment
,d<=h                                  // output if "no more than half of string"
);

["results_for__michael_greer.txt.zip",
"Georg Feuerstein - Connecting the Dots.pdf",
"M People - Search for the Hero-ntuqTuc6HxM.mp4",
"index.html?v=QTR4WGVTUzFsV3d8NHxvcmlnaW5hbHx8MTExMTAxBHxodHRwOi8vLCwsLHRyLDcsMA%3D%3D.html",
"ol2DCE0SIyQC(173).pdf",
"d41d8cd98f00b204e9800998ecf8427e.md5",
"12792331_807918856008495_7076645197310150318_o.jpg"]
.forEach(x=>document.body.innerHTML+='<pre>"'+x+'" => '+f(x)+'</pre>')