हानिपूर्ण या दोषरहित


18

एक ऑडियो फ़ाइल को देखते हुए, यह निर्धारित करें कि क्या यह हानिपूर्ण प्रारूप में है या दोषरहित प्रारूप में। इस चुनौती के प्रयोजनों के लिए, केवल निम्नलिखित स्वरूपों को वर्गीकृत करने की आवश्यकता है:

नियम

  • यदि इनपुट को फ़ाइल नाम के रूप में लिया जाता है, तो फ़ाइल नाम के बारे में कोई धारणा नहीं बनाई जानी चाहिए (उदाहरण के लिए प्रारूप के लिए सही होना या एक्सटेंशन मौजूद नहीं है)।
  • इनपुट फ़ाइलों में कोई ID3 या APEv2 मेटाडेटा मौजूद नहीं होगा।
  • किसी भी दो अद्वितीय और अलग-अलग आउटपुट का उपयोग किया जा सकता है, जैसे कि 0और 1, lossyऔर lossless, fooऔर bar, आदि।

परीक्षण के मामलों

इस चुनौती के परीक्षण मामलों में यहाँ स्थित एक ज़िप फ़ाइल होती है जिसमें दो निर्देशिकाएँ होती हैं: lossyऔर lossless। प्रत्येक निर्देशिका में कई ऑडियो फाइलें होती हैं जो सभी 0.5-सेकंड 440 Hz साइन तरंगों के होते हैं, जो विभिन्न स्वरूपों में एन्कोडेड होती हैं। सभी ऑडियो फाइलों में ऊपर दिए गए स्वरूपों से मेल खाते एक्सटेंशन हैं, A440.m4aजो (एक एमपीईजी लेयर 4 कंटेनर में एएसी ऑडियो है) के अपवाद के साथ ।


" एक एमपीईजी लेयर 4 कंटेनर में एएसी ऑडियो " सवाल उठाता है: उत्तर के अन्य कंटेनर प्रारूपों को संभालने की क्या आवश्यकता है?
पीटर टेलर

@PeterTaylor केवल AAC को विशेष उल्लेख दिया गया था क्योंकि मुझे FFMPEG के माध्यम से MPEG लेयर 4 कंटेनर में एम्बेड किए बिना AAC ऑडियो प्रदान करने का कोई तरीका नहीं मिल सका। वोरबिस ऑडियो को ओग कंटेनर में रखा गया है (जैसा कि वोरबिस ऑडियो के लिए आदर्श है)। अन्य सभी स्टैंडअलोन प्रारूप हैं।
मेगो

क्या आप TTA फाइल के बारे में निश्चित हैं? युक्ति के अनुसार , TTA फाइलें जादू नंबर TTA1 या TTA2 से शुरू होनी चाहिए। FFM2 (आपकी फ़ाइल का मैजिक नंबर) FFmpeg स्ट्रीम के अनुरूप प्रतीत होता है। लिनक्स फ़ाइल TTA1 हेडर को पहचानती है, लेकिन FFM2 को नहीं।
डेनिस

इसके अलावा, क्या हम मान सकते हैं कि AAC हमेशा एक एमपीईजी लेयर 4 हेडर में होगी? यदि नहीं, तो हम क्या मान सकते हैं?
डेनिस

क्या हम फ़ाइल की सामग्री को इनपुट के रूप में ले सकते हैं या हमारे कोड को उन्हें पुनः प्राप्त करना है?
शैगी

जवाबों:


18

जेली , 7 5 बाइट्स

ƈƈeØA

हानिपूर्ण प्रारूप 0 लौटाता है , दोषरहित प्रारूप 1 लौटता है ।

इसे ऑनलाइन आज़माएं! (गिस्ट में पर्मलिंक)

पृष्ठभूमि

जिन प्रारूपों का हमें समर्थन करना है, उनमें निम्नलिखित मैजिक नंबर होते हैं, यानी वे इन बाइट्स से शुरू होते हैं।

Format    Header (text)       Header (hex)
-----------------------------------------------------------------------------------
AC3       .w                  0B 77
AMR       #!AMR               23 21 41 4D 52
AAC       ÿñP@..ü             FF F1 50 40 00 1F FC
  M4A     ... ftypM4A         00 00 00 20 66 74 79 70 4D 34 41 20
MP2       ÿû                  FF FB
MP3       ÿû                  FF FB
OGG       OggS                4F 67 67 53
WMA       0&²u.fÏ.¦Ù.ª.bÎl    30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C

AIFF      FORM????AIFF        46 4F 52 4D ?? ?? ?? ?? 41 49 46 46
FLAC      fLaC                66 4C 61 43
TTA       TTA1                54 54 41 31
  FFM2    FFM2                46 46 4D 32
WAV       RIFF????WAVE        52 49 46 46 ?? ?? ?? ?? 57 41 56 45

इंडेंटेड एंट्री पूर्ववर्ती प्रारूप के लिए कंटेनर हैं जो परीक्षण मामलों में दिखाई देते हैं। ?एक चर बाइट को दर्शाता है। .एक अनपेक्षित बाइट को दर्शाता है। अन्य सभी बाइट्स को उनके ISO 8859-1 चरित्र के रूप में प्रदर्शित किया जाता है।

केवल दूसरी बाइट को देखकर, हम प्रारूप को आसान तरीके से निर्धारित कर सकते हैं:

दोषरहित प्रारूपों में उनके दूसरे बाइट के रूप में एक बड़ा अक्षर होता है, जबकि हानिपूर्ण प्रारूप नहीं होते हैं।

यह काम किस प्रकार करता है

ƈƈeØA  Main link. No arguments.

ƈ      Read a char from STDIN and set the left argument to this character.
 ƈ     Read another char from STDIN and set the return value to this character.
   ØA  Yield the uppercase alphabet, i.e., "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  e    Exists; return 1 if the return value (second char on STDIN) belongs to the
       uppercase alphabet, 0 if not.

2
यह एक बहुत ही चतुर उपाय है।
मेघो

10

सी, 82 80 32 बाइट्स

से प्रेरित @ डेनिस के जवाब , इसे बहुत कम किया जा सकता है:

main(){return getchar()&200^64;}

स्टड करने के लिए फ़ाइल डेटा को पाइप करें। दोषरहित के लिए 0, या हानिरहित के लिए नॉनज़रो देता है।

या मूल लंबी जाँच करें:

char v[5];main(){scanf("%4c",v);return*v&&strstr("fLaC FORM RIFF TTA1 FFM2",v);}

स्टड करने के लिए फ़ाइल डेटा को पाइप करें। दोषरहित के लिए नॉनज़रो (1) देता है, या हानिपूर्ण के लिए 0।

मैं जो बता सकता हूं उससे, आपके द्वारा सूचीबद्ध सभी प्रारूपों में अलग-अलग मैजिक नंबर हैं (एआईएफएफ / डब्ल्यूएवी को छोड़कर, लेकिन वे दोनों वैसे भी दोषरहित हैं), इसलिए यह सिर्फ एक ज्ञात दोषरहित मूल्य के लिए उस मैजिक नंबर की जांच करता है। *v&& सिर्फ एक मेल बाइट (M4A) के साथ शुरू होने वाली मैचिंग फाइलों से बचाने के लिए है।

मैंने उन मूल्यों को शामिल किया है जो मुझे कल्पना पत्रक ( fLaC= FLAC, RIFF= WAV / AIFF, TTA1= TTA), और FORM= AIFF और में मिला हैFFM2 = TTA प्रदान की गई नमूना फाइलों से हैं (मैं केवल अनुमान लगा सकता हूं कि ये आवरण प्रारूप या बाद के संस्करण हैं)।


या एक छोटा लगता है-जैसे-धोखा विकल्प:

बैश + फ़ाइल, 61 बाइट्स

N="$(file "$1")";[[ $N = *": d"* || $N = *IF* || $N = *FL* ]]

एक तर्क के रूप में फ़ाइल नाम लेता है। दोषरहित के लिए 0, या हानिरहित के लिए नॉनज़रो देता है।

जैसा आप उम्मीद करते हैं वैसा ही करता है; पूछता है fileकि फ़िलाटाइप क्या है, फिर ज्ञात पैटर्न की जांच करता है। टीटीए मैच : d( : data), एआईएफएफ / डब्ल्यूएवी मैच IFऔर एफएलएसी मैच FL। दोषरहित परिणामों में से कोई भी इनमें से किसी से भी मेल नहीं खाता है, और मैंने परीक्षण किया है कि यह अभी भी काम करता है यदि फ़ाइल नाम हटा दिए जाते हैं।


परिक्षण:

for f in "$@"; do
    echo "Checking $f:";
    ./identify2 "$f" && echo "shorter C says LOSSLESS" || echo "shorter C says LOSSY";
    ./identify < "$f" && echo "longer C says LOSSY" || echo "longer C says LOSSLESS";
    ./identify.sh "$f" && echo "file says LOSSLESS" || echo "file says LOSSY";
done;

# This can be invoked to test all files at once with:
./identify_all.sh */*

अगर फ़ाइल एक्सटेंशन गलत है तो क्या आपका बैश समाधान भी काम करता है? "एक्सटेंशन को प्रारूप के लिए सही होने की गारंटी नहीं है", इसलिए आपको फ़ाइल को गलत एक्सटेंशन देने में सक्षम होना चाहिए और फिर भी यह काम करना चाहिए।
mbomb007

@ mbomb007 मैंने अभी मिलाए गए एक्सटेंशन के साथ परीक्षण किया है और यह अभी भी उन्हें ठीक पहचानता है। मुझे लगता fileहै कि किसी भी तरह से एक्सटेंशन पर भरोसा नहीं है (बहुत से उपयोगकर्ता बात जो एक एमपीईजी के लिए एक पीएनजी का नाम बदलने के रूप में समान है!)
डेव

7

जीएस 2, 3 बाइट्स

◄5ì

हानिपूर्ण प्रारूप 0 लौटाता है , दोषरहित प्रारूप 1 लौटता है

इसे ऑनलाइन आज़माएं!(गिस्ट में पर्मलिंक)

पृष्ठभूमि

जिन प्रारूपों का हमें समर्थन करना है, उनमें निम्नलिखित मैजिक नंबर होते हैं, यानी वे इन बाइट्स से शुरू होते हैं।

Format    Header (text)       Header (hex)
-----------------------------------------------------------------------------------
AC3       .w                  0B 77
AMR       #!AMR               23 21 41 4D 52
AAC       ÿñP@..ü             FF F1 50 40 00 1F FC
  M4A     ... ftypM4A         00 00 00 20 66 74 79 70 4D 34 41 20
MP2       ÿû                  FF FB
MP3       ÿû                  FF FB
OGG       OggS                4F 67 67 53
WMA       0&²u.fÏ.¦Ù.ª.bÎl    30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C

AIFF      FORM????AIFF        46 4F 52 4D ?? ?? ?? ?? 41 49 46 46
FLAC      fLaC                66 4C 61 43
TTA       TTA1                54 54 41 31
  FFM2    FFM2                46 46 4D 32
WAV       RIFF????WAVE        52 49 46 46 ?? ?? ?? ?? 57 41 56 45

इंडेंटेड एंट्री पूर्ववर्ती प्रारूप के लिए कंटेनर हैं जो परीक्षण मामलों में दिखाई देते हैं। ?एक चर बाइट को दर्शाता है। .एक अनपेक्षित बाइट को दर्शाता है। अन्य सभी बाइट्स को उनके ISO 8859-1 चरित्र के रूप में प्रदर्शित किया जाता है।

केवल दूसरी बाइट को देखकर, हम प्रारूप को आसान तरीके से निर्धारित कर सकते हैं:

दोषरहित प्रारूपों में उनके दूसरे बाइट के रूप में एक बड़ा अक्षर होता है, जबकि हानिपूर्ण प्रारूप नहीं होते हैं।

यह काम किस प्रकार करता है

     (implcit) Push the entire input from STDIN as a string on the stack.
◄    Push 1.
 5   Get the strings character at index 1, i.e., its second character.
  ì  Test if the character is an uppercase letter.

2

जावास्क्रिप्ट (ईएस 6), 20 बाइट्स

c=>/^[fFRT]/.test(c)

व्याख्या

फ़ाइल की सामग्री को एक इनपुट के रूप में लेता है और trueयदि फ़ाइल दोषरहित है या रिटर्न करता है, falseतो यह उस इनपुट के पहले चरित्र का परीक्षण करके हानिपूर्ण है f, यह देखने के लिए कि क्या यह एक F, Rया है T


कोशिश करो

फ़ाइल की सामग्री को इसमें पेस्ट करें textarea

f=
c=>/^[fFRT]/.test(c)
i.addEventListener("input",_=>console.log(f(i.value)))
<textarea id=i></textarea>


दूसरा प्रयास, 81 63 बाइट्स

किसी दिए गए URL से किसी फ़ाइल की सामग्री प्राप्त करता है, जो ओवरकिल हो जाती है।

u=>fetch(u).then(r=>r.text()).then(t=>alert(/^[fFRT]/.test(t)))

पहला प्रयास, १४६ ११६ 89 बाइट्स

माइम प्रकार के रूप में अमान्य एक्सटेंशनों से बंधा हुआ है और, जाहिर है, प्रतिक्रिया हेडर अतिरिक्त इनपुट के रूप में योग्य हैं।

u=>fetch(u).then(r=>alert(/aiff|flac|tta|wave|wav$/.test(r.headers.get("Content-Type"))))

वेब सर्वर आमतौर पर फाइल एक्सटेंशन के आधार पर MIME जेनरेट करते हैं, जो यहां के नियमों के खिलाफ है। क्या आपने जांच की है कि क्या यह बिना एक्सटेंशन के सेवा की गई फाइलों पर काम करता है? (यदि ऐसा होता है, तो आपको संभवतः उस सर्वर का नाम शामिल करना चाहिए जिसे आप "भाषा" के भाग के रूप में उपयोग कर रहे हैं)
डेव

1
@ बहुत सुंदर यकीन है कि वे नहीं करते हैं। MIME और एक्सटेंशन एक दूसरे पर बिल्कुल भी निर्भर नहीं हैं। यदि आप किसी फ़ाइल का एक्सटेंशन बदलते हैं और उसे अपलोड करते हैं, तो MIME प्रकार फ़ाइल के वास्तविक सामग्री का MIME है, न कि एक्सटेंशन का। हालांकि, हालांकि, URL के रूप में इनपुट लेने की अनुमति शायद नहीं है। मुझे यकीन नहीं है।
mbomb007

@ mbomb007 मुझे यकीन नहीं है कि आप ऐसा क्यों कहते हैं; माइम प्रकार एक इंटरनेट चीज़ है, न कि कोई फ़ाइल सिस्टम / फ़ाइल चीज़, और जिन सर्वरों के बारे में मुझे पता है, वे इसे कॉन्फ़िगर किए गए लुकअप का उपयोग करके विस्तार के आधार पर निर्धारित करेंगे (हेडर की सेवा के लिए; वे सेवा करने से पहले हर फ़ाइल का निरीक्षण नहीं करना चाहते हैं; यह)। उदाहरण के लिए अपाचे AddType <mime> <extension>, या IIS का लें <MimeMap>। बेशक एक विशिष्ट सेटअप या फ़ाइल होस्टिंग उपकरण एक उचित निरीक्षण कर सकता है, और जो कि सर्वर की पसंद को जवाब देने का हिस्सा बना देगा (क्योंकि यह सर्वर है जो फिलाटाइप का निर्धारण कर रहा है!)
डेव

1
मैंने .NET के साथ फ़ाइल सत्यापन किया है, और MIME प्रकार अपलोड होने से पहले एक्सटेंशन बदल जाने पर भी सामग्री से मेल खाता है।
mbomb007

@ mbomb007 तब आपने जो भी .NET घटक का उपयोग किया है, उसने अपलोड करने के दौरान या फ़ाइलों की सेवा के दौरान फ़ाइल निरीक्षण किया होगा (मैं प्रदर्शन के लिए अपलोड के दौरान अनुमान लगाता हूं, लेकिन आप कभी नहीं जानते)। इसलिए अपनी मूल टिप्पणी पर वापस जा रहा हूं, जिससे यह जवाब "जावास्क्रिप्ट + .NET सेवरलिफ्टएक्सवाईजेड" जैसा होगा। URL से इनपुट लेने के लिए, मैं देख सकता हूं कि आप क्यों झिझक रहे हैं, लेकिन व्यक्तिगत रूप से मैं इसे तब तक वैध मानूंगा जब तक कि सर्वर विकल्प का उल्लेख नहीं किया जाता। हो सकता है कि इस पर एक मौजूदा मेटा हो, लेकिन अंततः यह मेगो तक है।
डेव

1

चिप , 11 बाइट्स

~Z~S
t'G~aF

बेशर्मी से चिप में डेनिस की जेली का जवाब।

दोषरहित रिटर्न 0x0, हानिपूर्ण रिटर्न 0x1

इसे ऑनलाइन आज़माएँ , जिस्ट में लिंक (TIO रणनीति के लिए धन्यवाद डेनिस यहाँ)

के बारे में बताएं!

~Z~S
t'

यह भाग हाउसकीपिंग है: यह Sपहली बाइट को tमारता है , और दूसरे के बाद erminates।

G~aF

यह निर्णय का मांस है। प्रत्येक इनपुट बाइट बिट्स द्वारा पहुँचा जाता है HGFEDCBA। यदि Gसेट किया गया है, और Fनहीं है, तो इसका मतलब है कि बाइट सीमा के भीतर 0x40है 0x5f(जो लगभग 'अपरकेस' के बराबर है, और हाथ में कार्य के लिए पर्याप्त है)।

हालांकि, बाइट बचत के लिए, मैं इस निर्णय की विपरीत से G and (not F)करने के लिए (not G) or F, के बाद से या के चिप में निहित हो सकता है।

यह परिणामी सत्य / गलत मान तब रखा जाता है a, जो आउटपुट का सबसे कम बिट है। (अन्य सभी बिट्स शून्य होंगे)। TIO में, मैं आउटपुट को हेक्सडंप के माध्यम से चलाता हूं ताकि मान दिखाई दे।

समान रूप से, सी-ईश में, कोई ऐसा कहेगा:

out_byte = !(in_byte & 0x40) && (in_byte & 0x20)

1

क्यूबिक्स, 16 बाइट्स

$-!u'HIa'@/1@O<

नेट फॉर्म:

    $ -
    ! u
' H I a ' @ / 1
@ O < . . . . .
    . .
    . .

इसे स्वयं आज़माएं

आपको एक अलग सूची में फ़ाइल दशमलव बाइट मान इनपुट करना चाहिए। विभाजक कोई फर्क नहीं पड़ता, कुछ भी जो एक अंक या शून्य साइन नहीं है। कोड वास्तव में केवल पहले बाइट के बारे में परवाह करता है, इसलिए यदि आप चाहें तो आप बाकी फ़ाइल को छोड़ सकते हैं। कार्यक्रम 0दोषरहित, और 1हानिपूर्ण के लिए आउटपुट करता है । इसे यहाँ आज़माएँ ! डिफ़ॉल्ट इनपुट एक FLAC हेडर का उपयोग करता है।

व्याख्या

फ़ाइलों के बारे में अच्छी बात यह है कि (लगभग) उन सभी में एक तथाकथित जादू है। वे फ़ाइल के पहले कुछ बाइट्स हैं। अच्छा सॉफ्टवेयर फ़ाइल एक्सटेंशन की जांच नहीं करता है, बल्कि यह देखने के लिए फ़ाइल जादू है कि क्या यह एक निश्चित फ़ाइल को संभाल सकता है।

डेनिस ने संपीड़न प्रकार को खोजने के लिए इस जादू का उपयोग करने का एक तरीका ढूंढ लिया है, लेकिन इस तथ्य को कि उन्होंने पहली बाइट को त्याग दिया, मुझे एक विधि के साथ आने की कोशिश करना चाहता था जो दूसरे के बजाय पहले बाइट का उपयोग करता था। आखिरकार, यह समुदाय सभी बाइट्स को बचाने के बारे में है।

यहां विभिन्न फ़ाइल प्रकारों के पहले बाइट्स की एक सूची दी गई है। मैंने उन्हें दो समूहों में आदेश दिया: हानिरहित और दोषरहित। यहाँ दशमलव, हेक्साडेसिमल और बाइनरी में उनके पहले बाइट के मूल्य हैं। आप पहले से ही एक पैटर्न देख सकते हैं ...

Lossy:                  Lossless:
255:0xFF:0b11111111     102:0x66:0b01100110
 79:0x4F:0b01001111      84:0x54:0b01010100
 35:0x23:0b00100011      82:0x52:0b01010010
 11:0x0B:0b00001011      70:0x46:0b01000110
  0:0x00:0b00000000

मैंने जो पैटर्न देखा, वह यह था कि दूसरा बिट (बाएं से दाएं की गिनती) हमेशा "दोषरहित" बाइट्स पर था और पांचवां बिट हमेशा बंद था। यह संयोजन किसी भी हानिपूर्ण प्रारूप में दिखाई नहीं देता है। इसे "निकालने" के लिए, हम बस एक बाइनरी और (बाय 0b01001000 (=72)) करेंगे और फिर तुलना करेंगे 0b01000000 (=64)। यदि दोनों समान हैं, तो इनपुट प्रारूप दोषरहित है, अन्यथा यह हानिपूर्ण है।

अफसोस की बात यह है कि क्यूबिक्स के पास ऐसा कोई तुलनात्मक ऑपरेटर नहीं है, इसलिए मैंने घटाव का उपयोग किया (यदि परिणाम 64 है, तो यह 0 देता है, और इसका परिणाम 8 होता है, -56 या -64 अन्यथा। मैं इसके बाद वापस मिलूंगा।

सबसे पहले, चलो कार्यक्रम की शुरुआत में शुरू करते हैं। बाइनरी और aकमांड का उपयोग किया जाता है :

'HIa
'H   # Push 0b01001000 (72)
  I  # Push input
   a # Push input&72

फिर, हम घटाव का उपयोग करके 64 की तुलना करते हैं (ध्यान दें कि हम एक दर्पण को हिट करते हैं जो इस भाग के मध्य में आईपी को शीर्ष चेहरे [पहली पंक्ति, दूसरा चरित्र, दक्षिण की ओर इशारा करता है) को दर्शाता है)।

'@-
'@  # Push 0b01000000 (64)
  - # Subtract from (input&72)
    # Yields 0 for lossy, non-zero otherwise

IP द्वारा चालू किए जाने के बाद u, हम 1स्टैक को पुश करने के लिए कुछ नियंत्रण प्रवाह का उपयोग करते हैं यदि (और केवल यदि) तो स्टैक का शीर्ष गैर-शून्य है:

!$1
!   # if top = 0:
 $1 #   do nothing
    # else:
  1 #   push 1

क्यूब के चारों ओर लपेटने के बाद, हमने <निर्देश को मारा , जो आईपी लाइन को चौथी पंक्ति पर इंगित करता है। वह सब जो करना बाकी है वह आउटपुट और समाप्त है।

O@
O  # Output top of the stack as number
 @ # End program

तो, कार्यक्रम 0दोषरहित, और 1हानिपूर्ण के लिए आउटपुट करता है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.