چطوری فایل هایمان را به فایل باینری فشرده کنیم

سلام, من توی کتاب درسیم به اسم برنامه سازی و پایگاه داده خوندم که فایل های باینری حجم کمتری نسبت به کل فایل ها دارند, و همچنین اون روز هایی که من بازی میکردم وقتی بازی های کرک شده میگرفتم مثلا با کرک ریلود, فیتگرل اون هارو فشرده میکرد و مثلا بازی باحجم ۵۰ گیگ که توسط ریلود کرک شده بود, توسط فیلتگرل الان شده بود ۳۰ گیگ, و وقتی استخراج میکردم بعد از صرف کردن حدودا ۳ یا ۴ ساعت فایل به حجم اصلیش یعنی ۵۰ گیگ بر میگشت, وقتی به پوشه اکسترکت نشده فیتگرل برین چیزی که مشاهده میکنید اینه که یک فایل exe و چندین فایل bin هست که مشخصه فایل exe اسخراج کننده فایل های bin هست, البته حجم فایل فشرده فقط به فرمت و ساختار فایل مربوط نیست و چیز هایی مثل الگوریتم های فشرده سازی خیلی در حجم دخیل هستند مثل LZMA2 که حجم فایل را تا ده برابر کاهش میده اما سوال من این هست که چطوری فایل ها رو مثل فیتگرل حجمش رو کاهش بدم, و اونا رو bin کنم, ممونم

این حرف غلطه.
اولا که باید اشاره کنم همه‌ی فایلها واقعا باینری هستن. چیزی غیر از باینری نمیشه توی هارد ذخیره کرد. فایلهای متنی هم در حقیقت به شکل یک رشته‌ی اعداد دودویی ذخیره میشن.
ولی این چیزی‌که در عامیانه بهش میگیم «فایل باینری» منظور فایلیه که با ادیتور یا نرم‌افزار دیگه‌ای نمیشه بازش کرد و نمیشه خوندش و داخلش یه سری instruction برای CPU هست. (توضیح بیشتر در پایین مطلب)

بعد باید بگم که اون متن، احتمالا منظورش این بوده که «اگه ما یه دیتایی رو به شکل مثلا json ذخیره کنیم حجمش خیلی بیشتر از این میشه که اون دیتا رو بدون فرمت قابل خواندن توسط انسان ذخیره کنیم»
یه مثالش میتونه عکس باشه. مثلا یه عکس PNG، اطلاعات پیکسلها رو به یه روشی ذخیره میکنه که فقط توسط لایبرری مخصوصش قابل خوندن هست. اگه بخواد اطلاعات رنگ RGBA هر پیکسل رو به شکل text و با انکدینگ UTF-8 بنویسه توی فایل (که مثلا من بتونم توی یه ادیتور بازش کنم و پیکسل سوم رو تغییر بدم) حجم فایل بسیار بسیار زیادتر میشه و نمایشش توسط کامپیوتر بسیار بسیار سختتر و کندتر.


این قضیش کلا فرق میکنه. اون بازی که ما دانلود میکنیم یا از توی یه دیسک میخونیم و extract میکنیم تا در مرحله‌ی دوم، نصب واقعیش انجام بشه، صرفا با یه الگوریتم خوب، فشرده شده.

با نرم‌افزار 7zip

البته هرکسی میتونه الگوریتمهای فشرده‌سازی رو خودش پیاده‌سازی کنه (الگوریتمهای آزاد رو!).
داکیومنتهاشون توی سایت IETF موجود هست و کسانی که لایبرری مینویسن برای یه زبان برنامه‌نویسی، از این داکیومنتها استفاده میکنن. مثلا:
https://tools.ietf.org/html/draft-diaz-lzip-01
اینم بگم که هرکسی میتونه این داکیومنتها رو بخونه و به تیم توسعه‌دهندش کمک کنه برای ارائه‌ی ورژن بهتری از این استانداردها.


توضیح درمورد بازکردن فایلهای باینری:
تصحیح میکنم. میشه خوند و ادیت کرد، ولی نه به روشهای مرسوم. مثلا با hexl-mode توی ایمکس میشه hex این فایلهای باینری رو دید و ادیت کرد یا مثلا با objdump میشه کدهای اسمبلی یک نرم‌افزار کامپایل شده رو دید، به هر زبانی که نوشته شده باشه! بعد میشه با hexl ادیتش کرد!!! کسانی که برای یه نرم‌افزار یا بازی، کرک مینویسن یا نسخه‌ی کرک شده‌ی نرم‌افزار رو ارائه میدن، همینکار رو میکنن.
کسانی که میخوان نرم‌افزاری که خودشون نوشتن رو از نظر امنیت بررسی کنن یا مثلا ببینن که فلان جای کار توسط کامپایلر به چه شکلی کامپایل شده و آیا میشه راندمانش رو بالاتر برد هم از همین روش استفاده میکنن برای بررسی نتیجه‌ی نهایی کار کامپایلرشون.

3 پسندیده

بله دقیقا و من دنبال برنامه ای هستم که بشه فایل هام رو به باینری تبدیل کنم مثلا فرض کنید الان یک فیلم با فرمت mp4 به راحتی برای یک پلیر قابل خوندن هست و این فیلم به صورت باینری روی هارد ذخیره شده, من دنبال متد و یا روشی هستم که بشه فایل رو کامل باینری کنم و چیزی که قراره من با hexl ببینم همون چیزی باشه که روی هارد هست, و این کارم باعث بشه که فایل من حجمش کاهش پیدا کنه

این کارو کردم و حتی قسمت -mx=9 level of compression = 9 (Ultra) رو روی اخرین درجه یعنی 9 قرار دادم ولی فایل 14 گیگی من همون بود در نهایت فقط bz2 بود که تونست فایل من رو 13.9 گیگ بکنه

همه‌ی فایلها «کامل» باینری هستن.
احتمالا منظور شما «فشرده‌سازی» باشه.

همیشه چیزی که با hexl میبینید، همون چیزیه که روی هارد هست!

به خاطر اینکه اون فایل شما، همینطوریش هم دیتای تکراری خاصی نداشته که نرم‌افزار فشرده‌سازی، بخواد حجم رو کم کنه.
نرم‌افزارها جادو نمیکنن! میگردن دنبال دیتاهای تکراری و اونها رو توی یه lookup table قرار میدن بعد به جای اون دیتا، آدرسش توی lookup table رو مینویسن. اینطوری به جای اینکه اون چیز، دو یا چند بار توی فایل تکرار شده باشه، فقط یک بار توی lookup table ثبت میشه و بعد هرجا که لازم بود قرار بگیره به جاش ‌آدرسش توی جدول نوشته میشه.
البته این یکی از روشهای فشرده‌سازیه.

شما همین‌کار رو با سورس‌کدهای یه پروژه انجام بدید. ۱۰۰گیگ سورس‌کد رو میشه تبدیل کرد به ۱۰مگابایت فایل فشرده.
میزان فشرده سازی فایلها، بستگی کامل به نوعشون (یا بهتره بگم میزان پترن‌هایی که توی اون فایلها تکرار میشن) داره.

1 پسندیده

بله کاملا باینری هستن, نمیدونم چطوری منظورم رو بیان کنم, ببینید من دنبال روشی هستم که مثل فیتگرل دقیقا فایل هارو طوری ذخیره کنم که حجمشون خیلی خیلی کم بشن و دوست دارم بدونم که فیتگرل از چه روشی و متدی این کار رو میکنه و ایا فرمت فایل های bin هست که باعث شده حجم ها چنین کم بشن

بله من یک فایل دارم که با برنامه crunch تمام حروف هشت رقمی از 0 تا 9 رو ساختم و بعد حجم این فایل نزدیک 1 گیگ بود اما فایل فشرده سازی شده کلا 11 مگ هستش

الگوریتم های compression یا فشرده سازی با توجه به نوع داده و طوری که نوشته شدن موثر هستن
الگوریتم فشرده سازی داده ی نوشته شاید اصلا هیچ تاثیری روی داده تصویری نداشته باشه
الگوریتم های فشرده سازی باینری هم پویا عزیز گفت باید تکرار توش زیاد باشه تا الگوریتم های snappy یا غیره خوب کار کنند با هاشون

3 پسندیده

خب یه بار فایلهای اون بازی رو با همین 7zip فشرده کنید. مثل فیتگرل فشرده میشه!
در تئوری، باید دقیقا همونطور بشه، اگه از همون الگوریتم فشرده سازی استفاده کرده باشن.

اگه منظورتون از فرمت، پسوند فایل هست، هیچ‌گونه تاثیری در هیچ‌چیزی نداره. یعنی رسما «لولو سر خرمن» هستن. (البته ویندوز خیلی بهشون علاقه‌داره)
چیزی که در تعیین نوع فایل تاثیرگذار هست، ۲ خط اول فایل (اصطلاحا بهش میگن دو‌خط. درمورد فایلهای باینری یعنی چند بایت اول) هست.
مثلا یه عکس PNG رو اگه با hexl یا حتی با یه text editor باز کنیم، اولش اینو میبینیم:

PNG IHDR

یا jpeg:

JFIF

یا یک نرم‌افزار کامپایل شده برای x86-64:

/lib64/ld-linux-x86-64.so.2

من با نرم‌افزار strings (تحت ترمینال) دارم بخشهایی از فایل رو که چندتا کاراکتر ascii کنار هم هست رو میخونم.

در حقیقت این چیزیه که باعث تمایز انواع مختلف فایلها میشه و سیستم‌عامل (اگه معقول باشه. نه ویندوز!) از روی این میفهمه که باید چیکار کنه و با چه نرم‌افزاری اجراش کنه.
البته بخشهایی که قابل print نیستن (و نرم‌افزار strings اونها رو نمیبینه هم مهم هستن. به کل اون بخش ابتدایی فایلها میگن magic number. مطالعه‌ی بیشتر:


و جواب سوال شما «آیا فرمت فایلها هست که باعث شده حجم اینقدر کم بشه؟»
به نوعی بله. همونطور که سام عزیز گفت، بستگی به نوع فایلی داره که داریم فشرده میکنیم. مثلا فایلهای DICOM (فرمت رایج فایلهای پزشکی) شاید بیشتر از ۸۰٪ش از 0 پر شده باشه. اینو خیلی راحت میشه فشرده کرد و از gzip برای فشرده سازیش استفاده‌ی زیادی میشه چون میتونه به صورت stream کار کنه و لازم نیست حتما کل فایل رو داشته باشیم برای compress کردنش.
چرا فایل Dicom بیشترش از 0 پر شده؟ استانداردش اینطوری بوده که padding زیادی داشته باشه. فایل png هم یه کم padding اولش داره (بین magic string و دیتای اصلی) همه‌ی فایلها همینطور هستن. البته این میزان padding خیلی کمه)

اگه فایل شما، دیتای تکراری زیادی داشته باشه (حالا میتونه padding باشه که با 0x0000 (صفر ۱۶ بیتی) پر شده باشه یا با متنهای تکراری (اگه سورس‌کد باشه که کلماتی مثل print و include توش زیاد تکرار میشن)

2 پسندیده

ممنونم لطف کردین, این کارو کردم حجم فایل نصب شده 3.9 GB بود بعد از فشرده سازی با 7z شد 700MB و همچنین فایل فشرده فیتگرل 600MB بود

1 پسندیده

پیشنهاد میکنم نیم نگاهی به ابزار zstd که توسط facebook ساخته شده بیاندازید
من قبلا فایل دیتابیس با حجم 5 گیگ رو تا حجم 200 مگ فشرده سازی کردم
برا فایل های غیرمتنی فکر کنم باید اول gz بکنین بعد zstd بکنین
برای فایل های متنی که خیلی برام کاربری بوده و سرعت خوبی داره :slight_smile:

Github : https://facebook.github.io/zstd

3 پسندیده

میدونم بحث ما درمورد میزان فشرده‌سازی بود ولی فقط به عنوان یه نکته‌ی کوتاه بگم که این قضیه، تنها فاکتور برای انتخاب الگوریتم نیست و همونطور که سام عزیز اشاره کرد، الگوریتمها با توجه به نوع داده طراحی میشن.

یه مثال میتونه gzip باشه که توانایی اینو داره که به صورت stream کار کنه.
یه الگوریتم دیگه که اخیرا بهش برخورد کردم، Huffman coding هست که برای کار، به کمتر از 1KB رم نیاز داره! بسیار مناسب برای سیستم‌های embded که شاید کل رم سیستم ۸کیلوبایت باشه!

3 پسندیده

اگر به این الگوریتم علاقه دارید به information theory و نوشته های Claude Shannon بخونید

1 پسندیده

سلام ممنون که وقت گذاشتین, روی لینوکسم نصب کردم و همون فایل که 3.9GB بود رو فشرده کردم با compression level 19 که نوشته بود اخرین حد هست و فایل شد 870MB

1 پسندیده