Wykrywanie nazw plików przyjaznych dla człowieka

10

Wprowadzenie

Nazwy plików mogą być bardzo różne, od prostych blah.txtdo 303549020150514101638190-MSP0.txt. Ten pierwszy jest zwykle generowany przez człowieka, podczas gdy drugi jest często generowany maszynowo. Czy nie byłoby miło mieć prostą funkcję pozwalającą zgadywać, czy plik można uznać za „przyjazny dla człowieka”?

Inspirowany postem Eduarda Florinescu, który został usunięty. Jego pomysł był dobry, ale potrzebował tylko trochę rozwinięcia.

Wyzwanie

Napisz program lub funkcję w wybranym języku, który może pobrać ciąg znaków, i określ, czy jest on uważany za „przyjazny dla człowieka”, zgodnie z tym wyzwaniem.

Niektóre dalsze szczegóły i zasady są następujące:

  • Dane wejściowe będą ciągiem znaków składającym się z 95 drukowanych znaków ascii.
  • „przyjazny dla człowieka” należy zdefiniować w następujący sposób:
    • Wyklucz rozszerzenie w rozważaniu. Przedłużenie jest definiowane jako końcowy okres, po którym następuje seria znaków alfanumerycznych (zaledwie 1, aż 6).
    • Nie więcej niż połowa ciągu według długości (bez rozszerzenia) może składać się z następujących zdefiniowanych grup znaków (łącznie):
      • Znaki dziesiętne dłuższe niż 8 z rzędu.
      • Znaki szesnastkowe (duże x lub małe litery) składające się co najmniej z 16 wierszy (muszą składać się z liter i cyfr, z których co najmniej jedna trzecia znaków to cyfry).
      • Base64 znaki (wykorzystujące %+=jako znaki specjalne) co najmniej 12 z rzędu (muszą składać się z liter i cyfr, być wielkimi literami i z których co najmniej jedna trzecia znaków to wielkie litery).
    • Jeśli którakolwiek z powyższych grup pokrywa się w definicji (np. Taka, która kwalifikuje się jako base64, ale ma 8 cyfr z rzędu), wybierz najdłuższą z nich, aby ją wykluczyć.
  • Dane wyjściowe powinny być zgodne z prawdą lub fałszem, w zależności od tego, czy ciąg zostanie uznany za „przyjazny dla człowieka”, czy nie.
  • Załóż, że zostaną użyte tylko prawidłowe dane wejściowe. Nie martw się obsługą błędów.

Zwycięzca zostanie określony przez najkrótszy program / funkcję. Zostaną oni wybrani za co najmniej 7 dni lub jeśli / kiedy będzie wystarczająco dużo zgłoszeń. W przypadku remisu odpowiedź, która nadeszła wcześniej, wygrywa.

Przykłady

Oto kilka przykładów danych wejściowych i wyjściowych, które Twój kod powinien obsługiwać:

"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
Mwr247
źródło

Odpowiedzi:

1

JavaScript, 466 bajtów

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)

Wyjaśnienie:

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>')

oddalony
źródło