বেস 64 দৈর্ঘ্যের গণনা?


155

বেস 64 উইকি পড়ার পরে ...

আমি সূত্রটি কীভাবে কাজ করছে তা নির্ধারণের চেষ্টা করছি :

দৈর্ঘ্যের সাথে একটি স্ট্রিং দেওয়া হয়েছে n, বেস 64 দৈর্ঘ্য হবেএখানে চিত্র বর্ণনা লিখুন

যা হলো : 4*Math.Ceiling(((double)s.Length/3)))

আমি ইতিমধ্যে জানি যে বেস %4==0পাঠের দৈর্ঘ্যটি ডিকোডারকে জানাতে হবে 64

সিকোয়েন্সের জন্য প্যাডিংয়ের সর্বাধিক সংখ্যা হতে পারে =বা ==

উইকি: প্রতি ইনপুট বাইটের আউটপুট বাইটের সংখ্যা প্রায় 4/3 (33% ওভারহেড)

প্রশ্ন:

উপরের তথ্যগুলি আউটপুট দৈর্ঘ্যের সাথে কীভাবে নিষ্পত্তি হয় এখানে চিত্র বর্ণনা লিখুন?

উত্তর:


210

প্রতিটি অক্ষর 6 টি বিট ( log2(64) = 6) উপস্থাপন করতে ব্যবহৃত হয় ।

সুতরাং 4 টি চর প্রতিনিধিত্ব করতে ব্যবহৃত হয় 4 * 6 = 24 bits = 3 bytes

সুতরাং আপনার বাইটগুলি 4*(n/3)উপস্থাপন করতে চরগুলি দরকার nএবং এটি 4 এর একাধিক পর্যন্ত গোল করা দরকার।

4 এর একাধিক পর্যন্ত গোলাকার ফলে অব্যবহৃত প্যাডিং চরগুলির সংখ্যা অবশ্যই 0, 1, 2 বা 3 হবে।


প্যাডিং এখানে আসে?
রই নমির

1
আপনার যদি একটি বাইট ইনপুট থাকে তা বিবেচনা করুন। এটি আউটপুট চারটি অক্ষর উত্পাদন করবে। তবে ইনপুটটি এনকোড করতে কেবলমাত্র দুটি আউটপুট অক্ষর প্রয়োজন। সুতরাং দুটি অক্ষর প্যাডিং হবে।
ডেভিড শোয়ার্টজ

2
আউটপুট দৈর্ঘ্য সর্বদা 4 এর একাধিক পর্যন্ত গোল হয়, সুতরাং 1, 2 বা 3 ইনপুট বাইট => 4 অক্ষর; 4, 5 বা 6 ইনপুট বাইট => 8 টি অক্ষর; 7, 8 বা 9 ইনপুট বাইট => 12 টি অক্ষর।
পল আর

5
আমি উপরের উত্তরে এই সমস্ত ব্যাখ্যা করেছি: (i) প্রতিটি আউটপুট চর ইনপুটটির 6 টি বিট উপস্থাপন করে , (ii) 4 আউটপুট চরগুলি সুতরাং 4 * 6 = 24 বিট উপস্থাপন করে , (iii) 24 বিট 3 বাইট , (iv) 3 বাইট ইনপুট এর ফলস্বরূপ আউটপুট 4 অক্ষর ফলাফল, (v) আউটপুট অক্ষরের অনুপাত তাই ইনপুট বাইট 4 / 3.
পল আর

2
@ টেকি_28: আমি এটি 20 * 1024 বাইটের জন্য 27308 অক্ষর তৈরি করেছি, তবে আজ সকালে আমার কফি পান হয়নি।
পল আর

60

4 * n / 3 আনপ্যাডড দৈর্ঘ্য দেয়।

এবং প্যাডিংয়ের জন্য নিকটতম 4 এর একাধিক, এবং 4 হিসাবে 2 পাওয়ার বিটওয়াইজ লজিকাল অপারেশনগুলি ব্যবহার করতে পারে।

((4 * n / 3) + 3) & ~3

1
তুমি ঠিক! -> 4 * এন / 3 আনপ্যাডড দৈর্ঘ্য দেয়! উপরের উত্তরগুলি সঠিক নয়। -> ((4 * এন / 3) + 3) এবং ~ 3 সঠিক ফলাফল দেয়
ক্যাডবারি

উইন্ডোটির এপিআই ক্রিপটিনারিস্টোস্ট্রিংএ-এর জন্য একটি ইনপুট হিসাবে কাজ করে না।
টারমোপিকারো

শেল ব্যবহার করে লোকদের জন্য এটির বানানটি প্রকাশ করুন:$(( ((4 * n / 3) + 3) & ~3 ))
স্টারফাই

1
4 * n / 3ইতিমধ্যে ব্যর্থ হয়েছে n = 1, একটি বাইট দুটি অক্ষর ব্যবহার করে এনকোড করা হয়েছে, এবং ফলাফলটি পরিষ্কারভাবে একটি অক্ষর।
মার্টেন বোদেউয়েস

1
@ ক্রোগ যেমন লিখিত আছে যদি এন = 1 হয় তবে আপনি পূর্ণসংখ্যা ব্যবহার করে 4/3 = 1 পাবেন। যেমনটি আপনি ইঙ্গিত করেছেন, প্রত্যাশিত ফলাফলটি 1 নয়, 2
ম্যার্টেন বোদেউয়েস

25

রেফারেন্সের জন্য, বেস 64 এনকোডারটির দৈর্ঘ্যের সূত্রটি নীচে রয়েছে:

বেস 64 এনকোডার দৈর্ঘ্যের সূত্র

যেমনটি আপনি বলেছেন, nডেটা বাইটস দ্বারা প্রদত্ত একটি বেস 64 এনকোডার বেস 4n/364 অক্ষরের একটি স্ট্রিং তৈরি করবে । আরেকটি উপায় রাখুন, প্রতি 3 বাইট ডেটা ফলাফল 4 বেস 64 অক্ষরের ফলাফল করবে। সম্পাদনা : একটি মন্তব্য সঠিকভাবে উল্লেখ করেছে যে আমার পূর্বের গ্রাফিকটি প্যাডিংয়ের জন্য অ্যাকাউন্ট করে নি; সঠিক সূত্র হয় Ceiling(4n/3)

উইকিপিডিয়া নিবন্ধটি দেখায় ঠিক কীভাবে ASCII স্ট্রিংটি উদাহরণটিতে Man বেস 64 স্ট্রিংটিতে এনকোড TWFuকরেছে। ইনপুট স্ট্রিংটি 3 বাইট বা 24 বিট আকারের হয়, সুতরাং সূত্রটি সঠিকভাবে পূর্বাভাস দেয় যে আউটপুটটি 4 বাইট (বা 32 বিট) দীর্ঘ হবে:TWFu । প্রক্রিয়াটি Base৪ বেস 64 অক্ষরের মধ্যে একটিতে প্রতিটি 6 বিট ডেটা এনকোড করে, তাই 24-বিট ইনপুটটি 4 বেস64 অক্ষরের 6 টি ফলাফল দ্বারা বিভক্ত হয়।

আপনি একটি মন্তব্যে জিজ্ঞাসা করুন এনকোডিংয়ের আকারটি কী 123456হবে। মনে রাখবেন যে স্ট্রিংয়ের প্রতিটি অক্ষর 1 বাইট বা 8 বিট আকারের (ASCII / UTF8 এনকোডিং ধরে নিচ্ছি), আমরা 6 বাইট বা 48 বিট ডেটা এনকোড করছি। সমীকরণ অনুযায়ী, আমরা আউটপুট দৈর্ঘ্য হবে আশা করি (6 bytes / 3 bytes) * 4 characters = 8 characters

ফেলে 123456একটি করুন Base64- এনকোডার মধ্যে সৃষ্টি MTIzNDU2হয়, যা 8 টি অক্ষর দীর্ঘ, আমরা আশা করেছিলাম ঠিক যেমন।


5
এই সূত্রটি ব্যবহার করে, সচেতন হন যে এটি প্যাডড দৈর্ঘ্য দেয় না। সুতরাং আপনি একটি দীর্ঘ দৈর্ঘ্য থাকতে পারে।
স্পিলারিক্স

বেস 64 টেক্সট থেকে প্রত্যাশিত ডিকোডড বাইটগুলি গণনা করতে, আমি সূত্রটি ব্যবহার করি floor((3 * (length - padding)) / 4)। নিম্নলিখিত টুকরো পরীক্ষা করে দেখুন ।
কুর্ট ভ্যানগ্রাইফস্কেপ

13

পূর্ণসংখ্যার

সাধারণত আমরা ডাবল ব্যবহার করতে চাই না কারণ আমরা ভাসমান বিন্দু অপস, রাউন্ডিং ত্রুটি ইত্যাদি ব্যবহার করতে চাই না সেগুলি কেবল প্রয়োজনীয় নয়।

এর জন্য সিলিং বিভাগটি কীভাবে সম্পাদন করতে হবে তা মনে রাখা ভাল: ceil(x / y)ডাবলগুলিতে লেখা যেতে পারে(x + y - 1) / y (নেতিবাচক সংখ্যাগুলি এড়ানো চলাকালীন, তবে ওভারফ্লো থেকে সাবধান থাকা) ।

সুপাঠ্য

আপনি যদি পঠনযোগ্যতার জন্য যান তবে অবশ্যই আপনি এটি এর মতো প্রোগ্রামও করতে পারেন (জাভাতে উদাহরণস্বরূপ, সি এর জন্য আপনি অবশ্যই ম্যাক্রো ব্যবহার করতে পারেন):

public static int ceilDiv(int x, int y) {
    return (x + y - 1) / y;
}

public static int paddedBase64(int n) {
    int blocks = ceilDiv(n, 3);
    return blocks * 4;
}

public static int unpaddedBase64(int n) {
    int bits = 8 * n;
    return ceilDiv(bits, 6);
}

// test only
public static void main(String[] args) {
    for (int n = 0; n < 21; n++) {
        System.out.println("Base 64 padded: " + paddedBase64(n));
        System.out.println("Base 64 unpadded: " + unpaddedBase64(n));
    }
}

Inlined

padded

আমরা জানি যে আমাদের প্রতি 3 বাইট (বা তার চেয়ে কম) এর জন্য 4 টি অক্ষর ব্লক প্রয়োজন। সুতরাং সূত্রটি হয়ে যায় (x = n এবং y = 3 এর জন্য):

blocks = (bytes + 3 - 1) / 3
chars = blocks * 4

বা সংযুক্ত:

chars = ((bytes + 3 - 1) / 3) * 4

আপনার সংকলকটি অপ্টিমাইজ করবে 3 - 1, সুতরাং পঠনযোগ্যতা বজায় রাখার জন্য কেবল এটি ছেড়ে দিন।

Unpadded

আনপ্যাডেড ভেরিয়েন্টটি কম সাধারণ, এর জন্য আমরা মনে রাখি যে প্রত্যেককে আমাদের প্রতিটি 6 টি বিটের জন্য একটি চরিত্র প্রয়োজন, যা বৃত্তাকার হয়:

bits = bytes * 8
chars = (bits + 6 - 1) / 6

বা সংযুক্ত:

chars = (bytes * 8 + 6 - 1) / 6

তবে আমরা এখনও দুটি দ্বারা ভাগ করতে পারি (যদি আমরা চাই):

chars = (bytes * 4 + 3 - 1) / 3

অপাঠ্য

যদি আপনি আপনার সংকলককে আপনার জন্য চূড়ান্ত অপ্টিমাইজেশানগুলি করতে বিশ্বাস করেন না (বা আপনি যদি আপনার সহকর্মীদের বিভ্রান্ত করতে চান):

padded

((n + 2) / 3) << 2

Unpadded

((n << 2) | 2) / 3

সুতরাং আমরা গণনার দুটি লজিক্যাল উপায়, এবং আমাদের কোনও শাখা, বিট-অপস বা মডুলো অপের প্রয়োজন নেই - যদি না আমরা সত্যিই না চাই।

মন্তব্য:

  • স্পষ্টতই আপনাকে নাল টার্মিনেশন বাইট অন্তর্ভুক্ত করতে গণনাগুলিতে 1 যুক্ত করতে হতে পারে।
  • মাইমের জন্য আপনার সম্ভাব্য লাইন সমাপ্তি অক্ষর এবং এই জাতীয় যত্ন নিতে হবে (এর জন্য অন্যান্য উত্তরগুলি সন্ধান করুন)।

5

আমি মনে করি প্রদত্ত উত্তরগুলি মূল প্রশ্নের বিন্দু মিস করে, যা দৈর্ঘ্য n বাইটের প্রদত্ত বাইনারি স্ট্রিংয়ের জন্য বেস 64 এনকোডিংটি ফিট করার জন্য কত স্থান বরাদ্দ করা দরকার।

উত্তরটা হচ্ছে (floor(n / 3) + 1) * 4 + 1

এর মধ্যে প্যাডিং এবং একটি সমাপ্ত নাল চরিত্র অন্তর্ভুক্ত। আপনি যদি পূর্ণসংখ্যার পাটিগণিত করছেন তবে আপনার মেঝে কলের প্রয়োজন হতে পারে না।

প্যাডিং সহ একটি বেস 64৪ স্ট্রিংয়ের জন্য কোনও আংশিক খণ্ড সহ মূল স্ট্রিংয়ের প্রতি তিন বাইট অংশের জন্য চার বাইট দরকার requires প্যাডিং যুক্ত হওয়ার পরে স্ট্রিংয়ের শেষে অতিরিক্ত এক বা দুটি বাইট বেস 64 স্ট্রিংয়ে চারটি বাইটে রূপান্তরিত হবে। আপনার যদি খুব নির্দিষ্ট ব্যবহার না হয় তবে প্যাডিং যুক্ত করা ভাল, সাধারণত একটি সমান চরিত্র। আমি সিতে নাল চরিত্রের জন্য একটি অতিরিক্ত বাইট যুক্ত করেছি, কারণ এএসএসআইআই স্ট্রিংগুলি কিছুটা বিপজ্জনক এবং আপনার স্ট্রিংয়ের দৈর্ঘ্য আলাদাভাবে বহন করতে হবে।


5
আপনার সূত্রটি ভুল। এন = 3 বিবেচনা করুন, প্রত্যাশিত ফলাফল (নাল প্যাডিং ছাড়াই) 4, তবে আপনার সূত্রটি 8 টি প্রত্যাবর্তন করবে
CodeInChaos

5
আমি নাল টার্মিনেটর সহ আরও নির্বোধ বলে মনে করি, বিশেষত যেহেতু আমরা এখানে নেট সম্পর্কে কথা বলছি।
কোডসইনচায়োস 23'14

ক্রিপ্টবাইনারিটোস্ট্রিংএ ব্যবহার করে উইন্ডোতে সঠিকভাবে কাজ করে। এই জন্য আমার ভোট।
টারমোপিকারো

5

এখানে কেবি-তে স্ট্রিং হিসাবে একটি এনকোডড বেস 64 ফাইলের মূল আকার গণনা করার জন্য একটি ফাংশন রয়েছে:

private Double calcBase64SizeInKBytes(String base64String) {
    Double result = -1.0;
    if(StringUtils.isNotEmpty(base64String)) {
        Integer padding = 0;
        if(base64String.endsWith("==")) {
            padding = 2;
        }
        else {
            if (base64String.endsWith("=")) padding = 1;
        }
        result = (Math.ceil(base64String.length() / 4) * 3 ) - padding;
    }
    return result / 1000;
}

3

অন্য প্রত্যেকে বীজগণিত সূত্র নিয়ে বিতর্ক করছে, আমি বরং আমাকে বলার জন্য কেবল BASE64 ব্যবহার করব:

$ echo "Including padding, a base64 string requires four bytes for every three-byte chunk of the original string, including any partial chunks. One or two bytes extra at the end of the string will still get converted to four bytes in the base64 string when padding is added. Unless you have a very specific use, it is best to add the padding, usually an equals character. I added an extra byte for a null character in C, because ASCII strings without this are a little dangerous and you'd need to carry the string length separately."| wc -c

525

$ echo "Including padding, a base64 string requires four bytes for every three-byte chunk of the original string, including any partial chunks. One or two bytes extra at the end of the string will still get converted to four bytes in the base64 string when padding is added. Unless you have a very specific use, it is best to add the padding, usually an equals character. I added an extra byte for a null character in C, because ASCII strings without this are a little dangerous and you'd need to carry the string length separately." | base64 | wc -c

710

সুতরাং দেখে মনে হচ্ছে 4 টি বেস 64 অক্ষর দ্বারা প্রতিনিধিত্ব করা 3 বাইটের সূত্রটি সঠিক বলে মনে হচ্ছে।


1
আমি গণনার বিপরীতে কিছু পেয়েছি যার জন্য অনেকগুলি মেমরি এবং সিপিইউ সময় প্রয়োজন হয় যখন গণনাগুলি 1 এনএস এবং এক বা দুটি রেজিস্টারে করা যায়।
মার্টেন বোদেউইস

সুতরাং যখন আপনি বাইনারি ডেটা অজানা পরিমাণের সাথে ডিল করার চেষ্টা করছেন - এটি কীভাবে সহায়তা করে?
ইউকেমনকি

প্রশ্ন হলো, সূত্র সম্পর্কে সব যা আউটপুটের আকার গণক সাহায্যের ছাড়া করুন Base64- নিজেই করছেন। এই উত্তরটি কিছু পরিস্থিতিতে কার্যকর হলেও এটি এই প্রশ্নের সাথে সহায়তা করে না।
আলেজান্দ্রো

3

(একটি সংক্ষিপ্ত অথচ সম্পূর্ণ ডেরাইভেশন দেওয়ার প্রয়াসে))

প্রতিটি ইনপুট বাইটে 8 টি বিট থাকে তাই এন ইনপুট বাইটের জন্য আমরা পাই:

n × 8 ইনপুট বিট

প্রতি 6 বিট একটি আউটপুট বাইট হয়, তাই:

সিল ( এন × 8/6 ) =  সিল ( এন × 4/3 ) আউটপুট বাইট

এটি প্যাডিং ছাড়াই।

প্যাডিং সহ, আমরা এটিকে একাধিক-চারটি আউটপুট বাইট পর্যন্ত গোল করব:

সিল ( সিল ( এন × 4/3 ) / 4) × 4 =  সিল ( এন × 4/3/4 ) × 4 =  সিল ( এন / 3) × 4 আউটপুট বাইট

নেস্টেড বিভাগগুলি দেখুনপ্রথম সমতার জন্য (উইকিপিডিয়া) ।

পূর্ণসংখ্যা arithmetics, ব্যবহার ছাদের নিচের পিঠ নির্মাণ ( এন / মি ) হিসাবে গণনা করা যাবে ( এন + + মি - 1) DIV আছে মি , অত আমরা পাই:

( এন) * 4 + 2) ডিভিড 3 প্যাডিং ছাড়াই

( n + 2) প্যাডিং সহ ভাগ 3 * 4

উদাহরণস্বরূপ:

 n   with padding    (n + 2) div 3 * 4    without padding   (n * 4 + 2) div 3 
------------------------------------------------------------------------------
 0                           0                                      0
 1   AA==                    4            AA                        2
 2   AAA=                    4            AAA                       3
 3   AAAA                    4            AAAA                      4
 4   AAAAAA==                8            AAAAAA                    6
 5   AAAAAAA=                8            AAAAAAA                   7
 6   AAAAAAAA                8            AAAAAAAA                  8
 7   AAAAAAAAAA==           12            AAAAAAAAAA               10
 8   AAAAAAAAAAA=           12            AAAAAAAAAAA              11
 9   AAAAAAAAAAAA           12            AAAAAAAAAAAA             12
10   AAAAAAAAAAAAAA==       16            AAAAAAAAAAAAAA           14
11   AAAAAAAAAAAAAAA=       16            AAAAAAAAAAAAAAA          15
12   AAAAAAAAAAAAAAAA       16            AAAAAAAAAAAAAAAA         16

শেষ অবধি, মাইম বেস 6464 এনকোডিংয়ের ক্ষেত্রে, প্রতি 76 76 আউটপুট বাইটের জন্য দুটি অতিরিক্ত বাইট (সিআর এলএফ) প্রয়োজন হয়, এটি একটি টার্মিনেটিং নিউলাইন প্রয়োজন কিনা তার উপর ভিত্তি করে বৃত্তাকার বা নীচে।


বিশদ বিশ্লেষণের জন্য ধন্যবাদ
পি সতীশ প্যাট্রো

2

আমার কাছে মনে হচ্ছে সঠিক সূত্রটি হওয়া উচিত:

n64 = 4 * (n / 3) + (n % 3 != 0 ? 4 : 0)

Ascii শূন্য পূরণটি আমলে নেওয়া হয় না - উইন্ডোজে কাজ করে না। (ক্রিপ্টবাইনারিটোস্ট্রিংএ)
টারমোপিকারো

1

আমি বিশ্বাস করি যে এই উত্তরটি সঠিক উত্তর যদি n% 3 শূন্য হয় না, তবে?

    (n + 3-n%3)
4 * ---------
       3

গণিত সংস্করণ:

SizeB64[n_] := If[Mod[n, 3] == 0, 4 n/3, 4 (n + 3 - Mod[n, 3])/3]

আনন্দ কর

সিপাহী


1

জাভাস্ক্রিপ্টে সহজ বাস্তবায়ন

function sizeOfBase64String(base64String) {
    if (!base64String) return 0;
    const padding = (base64String.match(/(=*)$/) || [])[1].length;
    return 4 * Math.ceil((base64String.length / 3)) - padding;
}

1

সি ভাষায় থাকা সমস্ত লোকের জন্য, এই দুটি ম্যাক্রোটি একবার দেখুন:

// calculate the size of 'output' buffer required for a 'input' buffer of length x during Base64 encoding operation
#define B64ENCODE_OUT_SAFESIZE(x) ((((x) + 3 - 1)/3) * 4 + 1) 

// calculate the size of 'output' buffer required for a 'input' buffer of length x during Base64 decoding operation
#define B64DECODE_OUT_SAFESIZE(x) (((x)*3)/4) 

এখান থেকে নেওয়া হয়েছে


1

অন্যান্য প্রতিক্রিয়াগুলিতে সরল সূত্রটি আমি দেখতে পাচ্ছি না। যুক্তিটি কভার করা হয়েছে তবে আমি আমার এম্বেড থাকা ব্যবহারের জন্য একটি সর্বাধিক প্রাথমিক ফর্মটি চেয়েছিলাম:

  Unpadded = ((4 * n) + 2) / 3

  Padded = 4 * ((n + 2) / 3)

দ্রষ্টব্য: আনপ্যাডেড গণনা গণনা করার সময় আমরা পূর্ণসংখ্যা বিভাগকে বৃত্তাকারে পরিণত করি অর্থাৎ বিভাজক -১ যোগ করি যা এই ক্ষেত্রে +2 হয়


0

উইন্ডোজগুলিতে - আমি মাইম 64৪ সাইজের বাফারের আকারটি অনুমান করতে চেয়েছিলাম, তবে সমস্ত সুনির্দিষ্ট গণনা সূত্রটি আমার পক্ষে কার্যকর হয়নি - অবশেষে আমি প্রায় আনুমানিক সূত্রটি দিয়ে শেষ করেছি:

খনি 64 স্ট্রিং বরাদ্দের আকার (আনুমানিক) = (((4 * ((বাইনারি বাফার আকার) + 1)) / 3) + 1)

সুতরাং শেষ +1 - এটি আসকি-শূন্যের জন্য ব্যবহৃত - শেষ অক্ষরটি শূন্য সমাপ্তি সংরক্ষণের জন্য বরাদ্দ করা দরকার - তবে "বাইনারি বাফার আকার" কেন + 1 - আমার সন্দেহ হয় যে এখানে কিছু মাইম 64 সমাপ্তি অক্ষর রয়েছে? অথবা এটি কিছু প্রান্তিককরণ সমস্যা হতে পারে।


0

যদি জেএসে @ পেড্রো সিলভা সমাধানটি অর্জনে আগ্রহী কেউ থাকে তবে আমি তার জন্য এই একই সমাধানটি পোর্ট করেছি:

const getBase64Size = (base64) => {
  let padding = base64.length
    ? getBase64Padding(base64)
    : 0
  return ((Math.ceil(base64.length / 4) * 3 ) - padding) / 1000
}

const getBase64Padding = (base64) => {
  return endsWith(base64, '==')
    ? 2
    : 1
}

const endsWith = (str, end) => {
  let charsFromEnd = end.length
  let extractedEnd = str.slice(-charsFromEnd)
  return extractedEnd === end
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.