کار با داده های باینری
header

مبلیما خرید مبل

کار با داده های باینری

working-with-binary-data

آیا bash می‌تواند داده‌های باینری را اداره کند؟

به طور اساسی پاسخ خیر است….

در حالیکه bash مشکلاتی به زیادی پوسته‌های قدیمی‌تر با آنها ندارد، باز هم نمی‌تواند داده‌های باینری اختیاری را پردازش نماید، و به طور اخص، متغیرهای پوسته ‎ ۱۰۰%‎ باینری خالص نیستند، بنابراین نمی‌توانید فایلهای باینری را در آنها ذخیره کنید.

شما می‌توانید داده‌های اسکی کُدگذاری شده یونیکس به یونیکس(uuencoded) را به این طریق در متغییر قرار دهید:

    var=$(uuencode /bin/ls ls)
    cd /somewhere/else
    uudecode <<<"$var"  # نقل‌قولها را فراموش نکنید
  • توجه: تفاوت سترگی میان uuencode یا uudecode گنو و یونیکس وجود دارد. با uudecode یونیکس، شما نمی‌توانید فایل خروجی تعیین کنید، همواره از نام فایل کدگذاری شده در داده اسکی استفاده می‌کند. من مثال قبلی را اصلاح کرده‌ام به طوری که در سیستم‌های یونیکس کار می‌کند. اگر شما تغییرات بیشتری ایجاد می‌کنید، لطفاً رویه‌گرایی گنو (GNUisms) را به کار نبرید. متشکرم.–GreyCat

یک نمونه که چنین موردی ممکن است گاهی در آن سودمند باشد، ذخیره کردن نقشه‌بیتی‌های کوچک موقتی، در هنگام کار کردن با netpbm است… در اینجا من به یک pnmnoraw زیرنویس ۱ اضافی در لوله متوسل شدم که باعث ایجاد فایلهای اسکی بزرگتر می‌شود و bash با ذخیره آنها مشکلی ندارد.

اگر احساس ماجراجویی دارید، این تجربه را ملاحظه نمایید:

# bindec.bash, سعی می‌کند داده‌های باینری را به اسکی دسیمال رمزگشایی کند‎
IFS=
while read -n1 x ;do
  case "$x" in
     '') echo empty ;;
     # ‏۲۵۶ سطر تولید شده توسط سطر فرمان زیر را در اینجا درج کنید ‎
     # for x in $(seq 0 255) ;do echo "     $'\\$(printf %o $x)') echo $x;;" ;done
  esac
done

و سپس داده باینری را به آن لوله‌کشی کنید، شاید اینطور :

    for x in $(seq 0 255) ;do echo -ne "\\$(printf %o $x)" ;done | bash bindec.bash | nl | less

این کد ایجاب می‌کند که کاراکتر ۰ به طور کلی از قلم انداخته شود، زیرا ما نمی‌توانیم آنرا با تولید کننده ورودی ایجاد کنیم، به راحتی برای خراب کردن اکثر فایلهای باینری که می‌خواهیم پردازش کنیم، کفایت می‌کند.

  • بلی، Bash به زبان C نوشته شده، و از معناشناسی این زبان برای مدیریت رشته‌ها — شامل بایت‌های NUL به عنوان حدفاصل رشته‌ها — در متغیرهایش استفاده می‌کند. شما نمی‌توانید به طور معقولی NUL را در متغیرهای Bash ذخیره نمایید. در حقیقت هرگز هم قرار نبوده به این صورت به کار برود. – GreyCat

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

برای cat کردن فایل باینری تنها با دستورات داخلی bash موقعی که برنامه خارجی در دسترس نباشد(یکبار وقتی نام فایل‎ /lib/libgcc_s.so.1‎ تغییر کرده بود، استفاده از این ترفند کارم را راه انداخت):

# باینری مطمئن bash فقط با دستورات داخلی cat شبیه‌سازی 
IFS=
while read -d '' -r -n1 x ; do
    case "$x" in
        '') printf "\x00";;
        *) printf "%s" "$x";;
    esac
done
  • من ترجیح خواهم داد از cat استفاده کنم. همچنین، آن ‎-n1‎ واقعاً لازم بود؟ -GreyCat
    • بدون ‎-n1‎ شما باید برای کار کردن با داده‌های بعد از آخرین ‎ \۰‎ خیلی با احتیاط باشید، موردی مانند این ‎[[ $x ]] && printf "%s" "%x"‎ بعد از حلقه. من این را بررسی نکرده‌ام که بدانم آیا کار می‌کند یا اینکه کافی هست. همچنین من نمی‌دانم اگر شما یک فایل بزرگ بدون هیچ ‎ \۰‎ را بخوانید چه اتفاقی می‌افتد –pgas

هر رقم در يک عدد باينری يک بيت (bit) ناميده می شود. بيت کوچکترين واحد اطلاعاتی در کامپيوتر است.

بيت ها به گروه های بزرگتری سازماندهی می شوند؛ در کامپيوترهای امروزی هر هشت بيت يک بايت (Byte) درنظر گرفته می شود که کوچکترين مکان آدرس پذير حافظه است (که می تواند متفاوت از مقدار حافظه واکشی شده درهربار مراجعه باشد). يک بايت می تواند حاوی يک دستورالعمل ماشين، يک کاراکتر، يا يک عدد باشد.

يک نيبل (nibble) نيمه يک بايت يا چهار بيت است.

نوع بزرگتر ذخيره سازی يک کلمه (word) است که روی پردازنده های اينتل ۲ بايت (۱۶ بيت) است. يک کلمه طول پيش فرض داده است که توسط طراح پردازنده انتخاب شده است و منعکس کننده برخی نکات سخت افزاری نظير گذرگاه های درونی و بيرونی است. کاميپوترهای شخصی اوليه با پردازنده های اينتل دارای عملوندهای ۱۶ بيتی بودند به همين دليل کلمه به صورت ۱۶ بيتی تعريف شد. در پردازنده های ديگر طول کلمه الزاما ۲ بايت نيست.

working-with-binary-data

يک کلمه مضاعف (doubleword) چهار بايت يا ۳۲ بيت طول دارد و يک کلمه چهارگانه (quadword) دارای هشت بايت يا ۶۴ بيت است.

endian

يک نکته مهم ديگر بعد از تعداد بيت ها ترتيب قرار گيری بايت های داده در حافظه است که بايد موردتوجه برنامه نويس اسمبلی باشد. درحينی که پردازنده به طور نامحسوس endian را استفاده می کند، برای دسترسی به داده های چندبايتی حافظه و کارکردن با هر بايت بطور جداگانه، دانستن endian حياتی است. endian ترتيب قرار گيری بايت ها در حافظه را برای داده های چندبايتی معين می کند. فرمت های زير برای ذخيره يک مقدار چندبايتی وجود دارد:

۱٫ Big-endian
• داده ها را به ترتيب طبيعی خودشان ذخيره می کند. بايت با ارزش در کمترين آدرس قرار می گيرد. اکثر پردازنده های RISC و Motorola 68300 از اين دسته هستند.
۲٫ Little-endian
• بايت با ارزش کمتر در آدرس های پائين تر حافظه ذخيره می شود. پردازنده های Intel x86 و Pentium از اين نمونه هستند.
۳٫ Bi-endian
• پردازنده هائی مانند Motorola/IBM PowerPC می تواند در مد big-endian يا little-endian تحت کنترل نرم افزار کار کند.

مثال. داده چهار بايتی هگزAABBCCDD را درنظر بگيريد. نحوه تخصيص حافظه به اين داده در دو فرمت endian به صورت زير نشان داده شده است. مشاهده می شود که اين دو فرمت عکس يکديگر هستند.

working-with-binary-data

روش های نمايش داده ها

اطلاعات معمولا به دو صورت استفاده می شوند: داده عددی ( صحيح و مميرشناور) و داده حرفی. نحوه نگهداری اطلاعات در حافظه را نمايش داده می گويند. روش های نگهداری داده ها بسته به نوع آنها متفاوت است.

working-with-binary-data

منبع : http://mehrmihan.ir/working-with-binary-data/

این مطلب را به اشتراک بگذارید :

a b