Replacing bits in a Byte Array C# - c#

I want to open a Bitmap File in C# as an array of bytes, and replace certain bytes within that array, and rewrite the Byte array back to disk as a bitmap again.
My current approach is to read into a byte[] array, then convert that array to a list to begin editing individual bytes.
originalBytes = File.ReadAllBytes(path);
List<byte> listBytes = new List<Byte>(originalBytes);
How does one go about replacing every nth byte in the array with a user configured/different byte each time and rewriting back to file?

no need in List<byte>
replaces every n-th byte with customByte
var n = 5;
byte customByte = 0xFF;
var bytes = File.ReadAllBytes(path);
for (var i = 0; i < bytes.Length; i++)
{
if (i%n == 0)
{
bytes[i] = customByte;
}
}
File.WriteAllBytes(path, bytes);

Assuming that you want to replace every nth byte with the same new byte, you could do something like this (shown for every 3rd byte):
int n = 3;
byte newValue = 0xFF;
for (int i = n; i < listBytes.Count; i += n)
{
listBytes[i] = newValue;
}
File.WriteAllBytes(path, listBytes.ToArray());
Of course, you could also do this with a fancy LINQ expression which would be harder to read i guess.

Technically, you can implement something like this:
// ReadAllBytes returns byte[] array, we have no need in List<byte>
byte[] data = File.ReadAllBytes(path);
// starting from 0 - int i = 0 - will ruin BMP header which we must spare
// if n is small, you may want to start from 2 * n, 3 * n etc.
// or from some fixed offset
for (int i = n; i < data.Length; i += n)
data[i] = yourValue;
File.WriteAllBytes(path, data);
Please notice, that Bitmap file has a header
https://en.wikipedia.org/wiki/BMP_file_format
that's why I've started loop from n, not from 0

Related

C#-converting array of byte to string gives weird output, does it mean the original value was coded?

I am trying to convert a hex string to a string. But when I do it the result is gibberish. I also tried converting hex to byte array to string but that didn't work as well. I was told the first 2 bytes are just "headers" but I wanted to see what they look like as well
string = "01012121b769010006583b001f8b0800000000000400ed9d6942eb381280afe203ccf0b45af6fc0b59204d3090e541fafe0799aab2e5555ee34000b9bbddc6b1ac5295964fa5c59c3326d56275d833c636f01f871bf0af1126644cc315de5362b1d86ce909cea2e36b10312e02c178040fb2c5711704ff6c9e8280332db8c440e7440a16c00197c1e1703ebc044182c739e1329236e87d1840101624810e18fc909cd781eb783d27f65187344cb028978604d96d0f4120a4d09c73cd384823452a4d42d2042e69b88d4d073c608ab3566992c45ebaa4512ad70d27415ef667d08d908c6bad41844237556992b34b1a1ebc63347a9a3417594a8b5bb25421cd6c96924e4b291024e2a9a578dc622987345f68a950de92a50a69e6b354e4b254a8404ed653a61cd27ca1a5cc4d9529337f99524e4b459c81727aca94439aa99612a9a5380fab96ba7f8108590c9612284d97a5b8a9584ac621586a09d184b2c752f8a8431ad0406129128414c423c558c87a2c554893eb66899692d144dd4099520e4bb1082140f4942987345f682911453764a9429ad92ca598cb52b1d61c94d25da61cd27ca1a594baa5325548339fa5a6b39f439a2fb4948e6ec952bac9c517d77e17b0df7c943e83a5c2f8962c5548339fa52e60bfa634532d25419a278843d6d86f7b38026d09a02d90a85b37a0bdba34103e60a16995e6ad531a1e8938d70d09b25c3d401263c184e8d38d439a2d5a0a9232561a60bfc539504cabaa6e5ef62b904673d40dc75cbc363a9526cdc5ab5c37cc182b0d7b7e4ba3480289d1841d965a2c022975e492461b5394291224d30db9352017278989a2b234814b1a0e5140e5cd4016b1602a6ae7e273621fade7e2ed7d6038a4dca11ba63417c85ce764b9372569cea512ce54ae1b4c30c097d54d6b095f9034f4a8439ad814ec374837e7c025cd60dd2c5a7403b978b181fc1ff1aa6e52690c3c6fb04c8134e6dd958bc1521afb45f55c2cd6787f42094fa5891dd2c01d8d49ff6469a48eb54b1a210df535419abcbe69e462c2c3549ad50e1e8854260def6a19eca32e6942eeb494160a6a934c1ad92a4d5895465869da4bb89546344ab89572a06e9a96e28d96a14f371db59f9572a06e1cd2842dd2b4eaa65b9a487333b44c352d55e4625b3cfb72f11b94f0ec519734a171e9c659a6faa589874b13376abf279086e95a995a1ddf89fd40698cfc37cf7185b61e0a69c228af8bd1e83113c121583f33dede6a66b9181f754813f2b0285324486aa908ee208936cbd4d9254d5aa6e2086401dd2863faca541c354bf83230a083aa6ecee77f2917836e946cb4e149d95225dd14f1f14edf5607df80342c8af29e2f2341b2760a983852ba5117b74853623f6ca7646b3bd551a64e0ba074168fd1cdf942dd20df6416714923b418aa9b8e5cccad9afb74837c933d5acfc5bb47ecf9d6cad466bf404ac7fa86675cdc56fb392c4524aae568124da5e14c147d061284740335b46671e6854ce36a72b13bdf8034cc8cce376909d7328e5df58d910cac65faea1b5daa6f84d6d2d6373d259c1e754883ada3a3be111cd94f67f9a6421467973454174b636c7dd3996fb247dd638dda706802146b196b849c25adbc86ba7ed4096406cc188baab7bdd9e352b65d35569e772a757aaa7f5b14edaa2141a8838c9a4b7d719dfdbfa6343c5853d9993812c14bd2902094bd0026388f7958e9ff35fc062569d0196062033df504a269ef8d667e037cd46d29e3b254085563c47a2cc5c52d59ca21cd175aaa24cda5961299df40e6edaaa1e24fce03f2fd0b9959eabe45372cef1b9774b3457d4fa91f539f4a5e23191224d58d821a29d6a97fbbbd4c35a5d9a26e4c38a5ed487d2a9143373cc61aaaa725a361ae346834bf6ea251ba49ce2e69a6ea465a9f8aaeea26f56240f2b8e2e4a76cf7a944a1ed7199d41980c4a1a195ef2853d66fc05dd2a01fa254dfacac6e8c84464a4ad44dbbbfa9248df537492a53bc93c7d0df54f79a2af2a9285eb4f2a96e9eb748401cea1b4822e9a6d2ae967c2a00fa6159375065826ee0491df7f954f05197342c2ca42141ac6e903978c5bf5df737d5a401864393a26e04ef96861e9d593750c2e7d68d14c2a11b011958484dba31b2e2fd7a69934608a507ea861ead48039c7e0f524a5e2b53bbc73d96702c53b2bbd58420ba5efb5199621d7eca96129e492344a9d54441b2768a615542e46c8c192e8dc6da4feb29ad26f99b44ad9d226958ccb1bf2dd2daafd5df14091b3475cf40be59a33491e8f53749973440bf91431a9cd6407e15d6e9190c9b962269daebe28e7111f2a9b070a8344ddd14d2e409eb9126f7a9442e6952f50eb354533785a5aaba69b75447ab49de2fa65cba41d7b61aad1b315c37a2d94e519f9957a549fd0692e1c8084b6bbf362f86e10dbe110b9ca1d33e9ed6ed53315a15f98604c94ab8827be91875bb87c7210da768c6f7d455e653d17aa86e1a7de39234b99a7b74937b31b8531a5d6a1906e8e67ca16eac8747858dba98bc18ba966fc895c10cb498b1ed4f39bd18284db3bec9bc18a32da5ad87a72853244856a644d64e759570a73438f2399e8b73dd48976e429abc9c8e98bbc7ef89fd1c96fa32dd38a599a69bbc9d12436bbf6bb6533cf33731e92ce1204de82ce1257f93d1ac5c174b0d55d71a1a674c448fbf49872e6922a05f5709371ac7ccc9528697c7612bf54d210d34323c8a05f419b6184d2bfba544418f3a7371c96352e46290112252dd251c0dd9928b2796a9722e8e46e5629c13c3dc3ddf09b958505d1c6b1e0eadfd9a962a72b1ad48fb4a3858ca3eea90268a4a3e8a1edd345b868a34a4e63edda4d2d0a38e121ec591936f309a98c98a57c0c1c5b2948b01dcb4a5adfe5161ddc27e7aa8340ef693eefaa65d9a72bea97b9415d6fd52e1541c9935d45a3c6cf68fd913682a9646dd7e3016cb87cdf6908541370bcfe67d57dcf834db9a72627ad819e0c7207f135670d063b47f3fbf9ea1170502e522d3cbf11ffb66fbff8fe3e9707fd8b25c07fc7559d642e68de26b8a80d974e1614356de003a336615c55c489cfd11947f647718bc9168018976cf2e2737587ad889e6a544833452e2ecb3be448be989c608ae92680989764fe32c5b3a9bd1594a344a13736853fa129dcf3bc84799da13cd4d2aa5b5749c0e505f98681e855024b6995ccae6c0735626b3e949e720373ca8a478093c8d4224a7a5c82ef158ab356642be141b712e0a175d417d5032a10d618f5ae986b8d22359ac30528c844582e9778cba612e45e6728e10156ab28345a7c25c6aa8b9947db3fdffc769481e15c2612e1bf2d465ae537f1ed558309dc31bd5da88463a4a89c6ba113a32f689f644ebe989c608ae92e8301b46698ea294139d0da894128d936f6265faabe0b09ee8a03dd142695b30534bab392ced2e98c2164ccadba9af32931054722a154c81bed4b460d2a5a3605a45cd5530595a30056af4e18d15ad2c48fe50a9de65dac29f0eabf4f5d415295d8a87fbd7f44f81632dc59f218f0d1335692aedf7196be4c5191f8e408f27cc362284ab8f05bdef2e621f28179377d0c6d07368bef3922287abd723497c27d919231502ee6df664913bc5b6ffdae7de3e286bc25bce9056a8c2ef70603382acfa70ccd2ce33ab31905f9412d038ea7741bfe7bc3485ec61f36a3302d90f949e3d48b683ff4a773225a4116b08fbfc5c17875141a0bf368bfd3ad8af0fc760f1faba3ba7096884807f64660fb65f1cd760b9f52ad826c1faed141c5f8e8b5d00d5cefd611f70b069f05fc8c206ca8188c8705abb85b089871b41f21732d13fa7dd9fe4ef822e860413d382490ac66d303e3098a260c606330383e969c1425730239cc6b1e6146cb7004baed042c797e0f5b45f3e2e0e70bd5d3ead8fff0b48431ccb69e87a4fde80432b4f21b6c943b0785827cb335556984fdde1b80db75a6f16a7dd3178dd2d28f472b1df6fd77ba830407877ce12910d4c7911040e168df09843f7dbe571fb0244ae62f78b722dacff7b7c3a4298b7d376bf5ee16ccc4e6d03c2af565b7c37e4e3e3e2637df84f7020dded1ff0fa651f6cd6eb43f0bc3867a5840bb0df66597d23d6c650703ffe24e7657a816d315cbc2ef619bde5e454fef9e30f365f70812f481b93bc22870a1c2a44b8b34e56c1fe65cdb16988a387cdc7b614399e2532243f62cd4f67496745674de790ce86ce119d633c83e478a6b03c0d0bcd5f2306013579088f9d288613c570a2184e14c38962c0734b3f2c12d7e887f17c7cb2bc58a68000bb6ee654ed870d8280663f6c10f9a4743e0b04b4f4c39c6b724afd30bb3ce754ed8771f485f725bad90f1b9ce8abe11ef5c3dc4b544b96ce56ab9e66e9870dc23d673f6c4edcebee878dc4bd1221cd897bbe1fe6fb61be1ff643fa61711e135d161d2f68bf2bfd3023bf793f0c13d038ea777d3fccf7c37c3fecbbf6c3b26e55a51f56eb5f8de987c5acda0f83ae87b31f062d3cf68338f58c38f58c38f58cc03e788ee81ce3192a613c53af4a50af4a50584161058515145698b46f357fcf4c188d45389b203153cfec29c051be4acf2c9d565e1a2ccad6c9ffadf4ccb4312aefa4bc0def99fd7dfc2b3f4afc23da3a291801b3e9c2c386acbca18e05e51f5b7b66e9227cdb8528d6e0b3120b65cbf1ff567a665cc605f5b6265a343a29ed8916da943b2918c10c891ed249b1ab39d34eca53e925a0226d0a16ca2ab995592169f055b8092feba43c9558e875ff82cd1946a457ce4e8accd63e38963e943a29d92a88bf953ee53073c906af0fcaa388ae3399cbd5338382c90b562d561194f368b6a0e06fa56786e526efa4b426bad133ebcaa3ca94797da682d9c3ebc59c849cd76b7954f5e6d10b78bd2b8f0ad5caeb52ba795ddbb572d96589d77585d74d18ea7e5ee729afab49bc7ec4bc00ac1fb553ba50779a9df798383388d249ecc651bf0b5ab5b3402ea37427d0b012a5272f0900c01f88f025f99e903e9ab6e5346c7642fa85d82cd9f362ff35d8fcf4b3b0998b166c7e020ac646e18d63658a7fa7d08c35b5ad25f387e02245e5f2af50756a2af1e5110be91ab140128af85fa8f8623c3b9f12f48fa1dfa3ec2927c3e20c20cfb09e613dc37a864d3e9161f54d326c7f1ebd2186e505c3f22ac38695a940c6c86fc9b02876e3a8dff50ceb19d633ec28868d6764d8ecd926caf29951967e0749bb5056cc8db2d9869c1594a54d1258a9c5ccb6e64caa1365c2a22d1b335126797cd74773d0b69a6e9f2893e5983c161bb2f2867a8b59feb10d65b37d3fad48c5d696257eb7bb5c261594555c451326ca04ed8956a12aa32c463043a247a32ca8a4780984c0a5312926d0251e2bbea1046ed84677a32c2e5883646811a669a935cc0b3b708a2dd53f1ad5c625b73b3b345136db52a482b2368f5a29ece622490565519bfdd3279a283b288f22d5cd642e07ca663b97141365560e94cdf63049aa13650615cc26cab6275acbb8327d629e82391a656b7914a4eacba31d287b491e15722ccaf2ac8ace2f4bec4a886cffc40663c0f40976c9f4897e801d38552215b67e34ee822ee7992a11f64d950080ddaf377f4a3c72f87593267e39cb62c1f8512c6bdc2c0b4f7cfc593e6ef10221f6390589bc82cc7f7f3358faf16f0c567f0cea4fac900692ac6400814c723cb7932ca7df71aba37692c55987f3926cb67d7a37c9661ba91fda4976f1ad4836dba5fd52926d4df42892353741b2a0920ac99a2b92ecf6be83123cc97a924d6e9d64473b650b64ca2ecb241b5749d60c20597e45927d432942f8159936bd1ac2b4c6c9b4d5bb50f23dd37aa6fd1ca6dddeff2ca695cccdb450a85266850b64da37ac35e1823cb097002e1f0cb8821f0070e5e5808b439cde55eb5db5bfcb559bede25b015cda3bb7a426bb9f6f0d707514e680dbda1fb904702182abe451956da46c452af60a6615c0a52d950f55c0d57198f4267a14e0aa2ae0420457cba31d805beb84697519e06a8e5bfb4ce984fd6cc0cdb1b640ddb900d73b6d3de07aa76d1a6036c0ed73da120063fb91312dfc4d5310f061b87072f048c0ad787071eda90370152700e60a61188032a1656a8756d82513796faef7e6fe2e6fae875d0fbbb705bb13e625880276451576b1c12cc1ae545f3c2fe16dc4bc04a95c885bbbeb7db81e71bd0f370d301a71959cc1873b9977c53487ee5cbc6b62ac5ed38ac33b77a7b28477ee7e2fe7eefd22707f85aca426fb41b24375ab3dc1d5f0adf626f02e4670953caaeef19b6cae8f9d950b66f6ddb3eaec0525f880291b17f02e4670b53cdac1bba09239795729d9cebb10577b1eedd8c6ec72e7ae524cf66f6376bac798e55d242f595cd64abe1c1bb7896e5e4c00ab1d8dbbb3b9792317cf716e33846087d373b05dad93e376b3059805c839dd23c502ea2c0e8775f200907358efff6e97eb20050f0fd61eac7f9fef58b42c5eebf31d434df9f167f792e005413421f5d55cc7ad73230c4174d4313722a2fd9e67c567ef2ef6eee25b77177b7cf6f87c5bf83c616ec46077b1e603f0997f0a3e8f711ca3d8ac7634eecee638f6d0eca1d97ba3678066d5b26bd9286ff454829ee88cbe80a0798c6d984a2ba0991cd09b202c3e40ce0ab42ac3247e311e90aaea80563266fdbed806414323c83fb4b997795b56c0645c854999ed3d5f34d469c8ca1b9a0d75f1e300983c3b7cb19bd24b309b1730196735f4462ca9ca5f8b553f4c62325a7db19b52432dee0f49962552133b5ce79b4086c5a2aa82324a6a6231aa5d8b1afb8318fd5c251c5cd5662e1d56b9ea9ae6b25c75762caaaa9a0ba4ea335737574d36d79461f8b0e0aab0ca555a55b92a1a3e0c3f334d8ddf1e0085ad1f8dbba0cb79684a45c3c02779593e3e1c06ed87f58a9f5e38fc5d1dd68be377a4a39fc22b8bcd8fe21516b7adeadf10a6a40d605e9bc1dd8247ea3f1282847504718c745377592a72e2d118b70ce96c3a7084136b\n24f439820e1c115847c9397164b50b221574e38880a6033fa4bd6ec791e15bac06c7c93862431ebbdab7e3c538022a397e168e405ca37004cd15169f6472e208971abf73a1d7ed38d2bb396c8123ede6eac39139cdd5812335735d15473acde57164148e802e67da6ed3e34811ec67e1c86a77d3140159b8a088bc1282bb0d8a384ea48888af811c623c2b46678e67d08a72528414f4bb107496e9b32dae0de35d1bbfdab5e159c2b3c40f6109efdaf02c61c379d786cbb5312794b4ba36668092d9c75bbc83e35b3938fc788b1f6ff92150e21d1c1e4a6cb82e07c76f8012b7a764cef196564fc905e32d2ac2a52a664e1c79021c815c5ec191d5f1bd3a4f53698d79aeb1fe50d9bfc7ad3f6c6bdfb2aac9e20846c06cbaa6b76f8e461d121df230178dd2db700c45f063c46b13a865acc269eb0f073218463043a2473318a86456c790d6ed8dfad338069313194c0e65b0c6046acf60e5c333d87c0c0659df3b866e7a46f0b745b7a79f856e9cb5a01b14a18f3fabe3112fd2f570174f9a699bb7ab68a75fd5356f7720b8c5da839b07b7df066e1347f4eae036fc5bc47e44af7cf8113d0f6ecc839b4db707b7db06b7094382c3c0ede26140837610515af8679a9bb40c8cd6bc826fe7f3bfb57dbf04e09b92b58d0b8cd0f6ef11c3801f87c7776d92e5dad6c7ed1b1718917e87dcc6624356de506f1acb3fb6eefbb50ca288e5e842e96d6e5c004010297da8e29b0965ffd86713dfda13ad5515df4cd6b85d96e8f1fb7e2d4b2fc145e14d7c5bea0d965e5c142ebaf1adde8ed55ae0854d3b364eeb10f5ca51c6d4fc0ebf1b9a8b57372eb079d44a01cd0aee4e57dbb800b53901df86e551c4b799cce5fa6a19164c95332ba5b7b97181829fb5aeed733ba86036372e18944769b786790ae6f8af968dcea31dcc7a491e9db2ef579435a1d9658959c10265668d78dccface212663dbca557610fbdee290483e7466d618009a81f8dbba0df79068187ee36c0fe2e76a7c5e6b87a3dfe01a20558f8bd88fadb761b582c6f024865d832336d09407a0695c145799300cd0a00cd2bbef2c3e5bd6a9d0f13ad46d1505aa5fd6795ce769e6dd91e40d05342777e8f015b8a59bfc7705a041167f1a59c3ac2cd78039c8a8986b6e6524e1de166bc794e05957c1aa79eca9b170de054caa35a5fcaa92336d8ba014ec5444316bd9453476cb075f39c3a3e8f4ee7d4ce3cea39f5624e05fd7a4ef59cfa399c7a5afc2c0f6c1bf09e1619c39e16fdc05b7e786ee0a58f2c28d303bcf494309f0bbcde31eb1db3b7ee98f5c0eb81d7036fb9c07d7fe0f58e590fbc9fea98fd0dc03bcac37b4de01de6e1fd12e0f51e5eefe1bd750faf9f89e06722f89908e502f7fd81d77b783df07a0f6f1ae06b3cbcd79cd230ccc33b604a8394dec3eb3dbcbfcdc3bb7b0cf0eb4315e0ddec17d525ef4669064d6afd9b61265fe47515e0c508ae924715245a2995c31ea5b701bc98c1aa1f4ac36f86852ceca7fc0b801723b85a1eed005e50c9a7012fc4d59e4785b922f0c63cec075e7539f08a3bd9f1cd307687fc40f2ddc5007ee973268760390e823151f5a371d77b7d3d047baf6f1ae06bbcbe50eb7dfcc1a6062eaeeaf575ec1485b40425862038a64f84313af32e2016b30331b5bb3aa80071061b051b86b84f76c5bbc6d37677c29694c38178a676d701c44458a0cd54244ee9cd8038870dc8b34058b206c4c308cb02b14d3c1f0ec43311d668201e0f1ba5f6794ed8f040ec8138b975200eaf07c49cd61bd7a46900f1459fce25d0e51a9e23d0950680b81b8d0bf83dd373e20ef5dd87c1dc9245f968dc054dcfb3bbc2efc2606e83718fc1c33178f7f83b30b84cb65f8ac104b82a9e1583b99afdd373633e17739ce57331c747fe4f649ef3dd8a5a89d0b55b1185acbcc1b15b51fee34417e9a6f4924a6b4b97786cc48a5eb496b37e2ee6f958d9ade8c29dd98fb3ecccde6eae90f76e2e359bb9ba86c7abe60a79dc67aee99b4b759a6bc2e652bcd85c8a5737978aa8c097e028fe3e9b4b91b0f5a37177b6cfc538db52d6c49fd735342fc7f31ff8136af0ef883e3f05467ed95760d2762dafa4aa7b75d67e44cae063be0273a4afc01ce92b3047fa0acc91f84138b77fe25264bfbbf842505dfe655f7ee9e08b515f7e111f7a225fa4212b6f683658c58fd3f8827643b42fe9e18b79bffcf23ceb975f3c5f78beb861be98edcb2fda8ce20b6a14b6ebc375006322eb7830f15f82298149f62518cb1e5963342798440423319e15a333bf004c4ca4e71eff1bb395f87196adc4db5bbaac92b260d2d84a7c5a4b77e156e2c759b6121feced696c25fe49de9ea7ddbcde9ee15b89f77a7b243c2f64314ad7b20244333069398f5eb0e479501e75ae00992b8f2a2c983cce4573af00313ac64c769c65c9f360046dcc54fd2404ade5d18b115445d1b43c3a6105c870049590d7afbb02a41b410ff974b9d2e4b731588a09a81f8dbbb3eda97e5358ea67bedd1eccfeb42dd6851cb8c57a8d5ce9779c19f7b4ab8cf211e6d61f76636ec796eb47da72fdd8b5e243d2efa9afae6d821be77e829b9fe0e627b8f9096e69c1f413dc7ede043739e40341734e7053d11dbfce0437e9fa7c50fdae9fe0e627b8f9096e69801f3ec1ad157d691d880c3bd776cc8ebe7e771fbfbbcfadefee03cfc79a8783d0f7bd1d7d47f876df1fdf4538097d6dc8ca1beae62affd8b59d6524f920f47d6f47df11beddf6449bdaf4823afa4e4bf494ed2c8b9740f550f876c33076e6d1e9e8dbbd9de5f8c5cea2f0ed8a9a6f370ecbe82bb8fe798b9d2951f5a371d7eff8e35dbe9f06c17ec71f07d7d2c3d8d438b7b80ce913c979158c102c86fb7f07edf8230d7f07088ef07c9b2b3b925956762493675eda9049d7cccbe4e29997a092e4b3665ed6a6f2cd3af37237cbcccbdd23ff47842e734535af60dd5c3664e50d7573957f9c3cf3b27809542f85b98c45a39b9d79290bafa0ac7a05e3a832ec2da26f34f39284ad1f8dbb7e65c7af9d40f92b577624ee099486c822afc1902c64c3bdd6b1b223a1951d09b9cf125ad991744ea08cf9ae952f180d458839f9c2afecf8562b3bd05c210b3bf982e61202123eb5f345efc878c1174f93f9c2867ceae28ba78bf90254f2f4597cb1ea9c56e7f9a2246cfd68dcfd992b3b3c600c5da171c35ce05e58b1da35b9e06922178c5e58014f3dddeac28add2c0b2bda3bb2591d61b9a0b1b0625a47f6c28515bb591656b4273acd5f79a21b0b2be6ecbd772fac28f7dea949ed6e5d4b0d925f58e11756f88515331160fccd17565002ea47e3ae5f58e147d93e87417fedc28a9a476bf4c28a26e6b60dac41d3bb0b98e6994b6bc0c28aff03c71fb271b76901000a\n\n"
This code is for getting to bytes and then converting it to string.
compString = compString.Substring(4);//taking the first 2 bytes out. 1 hex has 4 bits
byte[] byteArray = hexStringToByteArray(compString);
string result = System.Text.Encoding.ASCII.GetString(byteArray);
private byte[] hexStringToByteArray(string hexString)
{
hexString = hexString.Replace("\n", "");
int len = (hexString.Length - 2);
byte[] byteArray = new byte[len / 2];
for (int i = 0; i < len; i += 2)
{
byte b = byte.Parse(hexString.Substring(i, 2), NumberStyles.HexNumber);
byteArray[i / 2] = b;
}
return byteArray;
}
Any suggestions?
EDIT- Output was weird because it was compressed. I needed to decompress it. Thanks everyone

Search data from one array in another

What I'm trying to do is simple but it's just slooow. Basically I'm looping through data (byte array), converting some parts to a INT and then comparing it to RamCache with is also a byte array. The reason why I'm converting it to a INT is because it's 4 bytes so if 4 bytes are equal in some part of the RamCache array I know it's already 4 length equal.
And then from there I can see how many bytes are equal.
In short what this code must do:
Loop through the data array and take 4 bytes ,then look if it contains in the RamCache array. Currently the code below is slow when the data array and RamCache array contains 65535 bytes.
private unsafe SmartCacheInfo[] FindInCache(byte[] data, Action<SmartCacheInfo> callback)
{
List<SmartCacheInfo> ret = new List<SmartCacheInfo>();
fixed (byte* x = &(data[0]), XcachePtr = &(RamCache[0]))
{
Int32 Loops = data.Length >> 2;
int* cachePtr = (int*)XcachePtr;
int* dataPtr = (int*)x;
if (IndexWritten == 0)
return new SmartCacheInfo[0];
//this part is just horrible slow
for (int i = 0; i < data.Length; i++)
{
if (((data.Length - i) >> 2) == 0)
break;
int index = -1;
dataPtr = (int*)(x + i);
//get the index, alot faster then List.IndexOf
for (int j = 0; ; j++)
{
if (((IndexWritten - j) >> 2) == 0)
break;
if (dataPtr[0] == ((int*)(XcachePtr + j))[0])
{
index = j;
break;
}
}
if (index == -1)
{
//int not found, lets see how
SmartCacheInfo inf = new SmartCacheInfo(-1, i, 4, false);
inf.instruction = Instruction.NEWDATA;
i += inf.Length - 1; //-1... loop does +1
callback(inf);
}
else
{
SmartCacheInfo inf = new SmartCacheInfo(index, i, 0, true); //0 index for now just see what the length is of the MemCmp
inf.Length = MemCmp(data, i, RamCache, index);
ret.Add(inf);
i += inf.Length - 1; //-1... loop does +1
}
}
}
return ret.ToArray();
}
Double looping is what's making it so slow. The data array contains 65535 bytes and so goes for the RamCache array. This code is btw some part of the Cache system I'm working at it's for my SSP project.
Sort the RamCache array or a copy of the array and use a Array.BinarySearch. If you cannot sort it, create a HashSet of the RamCache.

Fast way to swap bytes in array from big endian to little endian in C#

I'm reading from a binary stream which is big-endian. The BitConverter class does this automatically. Unfortunately, the floating point conversion I need is not the same as BitConverter.ToSingle(byte[]) so I have my own routine from a co-worker. But the input byte[] needs to be in little-endian. Does anyone have a fast way to convert endianness of a byte[] array. Sure, I could swap each byte but there has got to be a trick. Thanks.
Here is a fast method for changing endianess for singles in a byte array:
public static unsafe void SwapSingles(byte[] data) {
int cnt = data.Length / 4;
fixed (byte* d = data) {
byte* p = d;
while (cnt-- > 0) {
byte a = *p;
p++;
byte b = *p;
*p = *(p + 1);
p++;
*p = b;
p++;
*(p - 3) = *p;
*p = a;
p++;
}
}
}
I use LINQ:
var bytes = new byte[] {0, 0, 0, 1};
var littleEndianBytes = bytes.Reverse().ToArray();
Single x = BitConverter.ToSingle(littleEndianBytes, 0);
You can also .Skip() and .Take() to your heart's content, or else use an index in the BitConverter methods.
What does the routine from your co-worker look like? If it accesses the bytes explicitly, you could change the code (or rather, create a separate method for big-endian data) instead of reversing the bytes.

Converting from byte[] to string

I have the following code:
using (BinaryReader br = new BinaryReader(
File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{
int pos = 0;
int length = (int) br.BaseStream.Length;
while (pos < length)
{
b[pos] = br.ReadByte();
pos++;
}
pos = 0;
while (pos < length)
{
Console.WriteLine(Convert.ToString(b[pos]));
pos++;
}
}
The FILE_PATH is a const string that contains the path to the binary file being read.
The binary file is a mixture of integers and characters.
The integers are 1 bytes each and each character is written to the file as 2 bytes.
For example, the file has the following data :
1HELLO HOW ARE YOU45YOU ARE LOOKING GREAT //and so on
Please note: Each integer is associated with the string of characters following it. So 1 is associated with "HELLO HOW ARE YOU" and 45 with "YOU ARE LOOKING GREAT" and so on.
Now the binary is written (I do not know why but I have to live with this) such that '1' will take only 1 byte while 'H' (and other characters) take 2 bytes each.
So here is what the file actually contains:
0100480045..and so on
Heres the breakdown:
01 is the first byte for the integer 1
0048 are the 2 bytes for 'H' (H is 48 in Hex)
0045 are the 2 bytes for 'E' (E = 0x45)
and so on..
I want my Console to print human readable format out of this file: That I want it to print "1 HELLO HOW ARE YOU" and then "45 YOU ARE LOOKING GREAT" and so on...
Is what I am doing correct? Is there an easier/efficient way?
My line Console.WriteLine(Convert.ToString(b[pos])); does nothing but prints the integer value and not the actual character I want. It is OK for integers in the file but then how do I read out characters?
Any help would be much appreciated.
Thanks
I think what you are looking for is Encoding.GetString.
Since your string data is composed of 2 byte characters, how you can get your string out is:
for (int i = 0; i < b.Length; i++)
{
byte curByte = b[i];
// Assuming that the first byte of a 2-byte character sequence will be 0
if (curByte != 0)
{
// This is a 1 byte number
Console.WriteLine(Convert.ToString(curByte));
}
else
{
// This is a 2 byte character. Print it out.
Console.WriteLine(Encoding.Unicode.GetString(b, i, 2));
// We consumed the next character as well, no need to deal with it
// in the next round of the loop.
i++;
}
}
You can use String System.Text.UnicodeEncoding.GetString() which takes a byte[] array and produces a string.
I found this link very useful
Note that this is not the same as just blindly copying the bytes from the byte[] array into a hunk of memory and calling it a string. The GetString() method must validate the bytes and forbid invalid surrogates, for example.
using (BinaryReader br = new BinaryReader(File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{
int length = (int)br.BaseStream.Length;
byte[] buffer = new byte[length * 2];
int bufferPosition = 0;
while (pos < length)
{
byte b = br.ReadByte();
if(b < 10)
{
buffer[bufferPosition] = 0;
buffer[bufferPosition + 1] = b + 0x30;
pos++;
}
else
{
buffer[bufferPosition] = b;
buffer[bufferPosition + 1] = br.ReadByte();
pos += 2;
}
bufferPosition += 2;
}
Console.WriteLine(System.Text.Encoding.Unicode.GetString(buffer, 0, bufferPosition));
}

Why do I get the following output when inverting bits in a byte?

Assumption:
Converting a
byte[] from Little Endian to Big
Endian means inverting the order of the bits in
each byte of the byte[].
Assuming this is correct, I tried the following to understand this:
byte[] data = new byte[] { 1, 2, 3, 4, 5, 15, 24 };
byte[] inverted = ToBig(data);
var little = new BitArray(data);
var big = new BitArray(inverted);
int i = 1;
foreach (bool b in little)
{
Console.Write(b ? "1" : "0");
if (i == 8)
{
i = 0;
Console.Write(" ");
}
i++;
}
Console.WriteLine();
i = 1;
foreach (bool b in big)
{
Console.Write(b ? "1" : "0");
if (i == 8)
{
i = 0;
Console.Write(" ");
}
i++;
}
Console.WriteLine();
Console.WriteLine(BitConverter.ToString(data));
Console.WriteLine(BitConverter.ToString(ToBig(data)));
foreach (byte b in data)
{
Console.Write("{0} ", b);
}
Console.WriteLine();
foreach (byte b in inverted)
{
Console.Write("{0} ", b);
}
The convert method:
private static byte[] ToBig(byte[] data)
{
byte[] inverted = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
var bits = new BitArray(new byte[] { data[i] });
var invertedBits = new BitArray(bits.Count);
int x = 0;
for (int p = bits.Count - 1; p >= 0; p--)
{
invertedBits[x] = bits[p];
x++;
}
invertedBits.CopyTo(inverted, i);
}
return inverted;
}
The output of this little application is different from what I expected:
00000001 00000010 00000011 00000100 00000101 00001111 00011000
00000001 00000010 00000011 00000100 00000101 00001111 00011000
80-40-C0-20-A0-F0-18
01-02-03-04-05-0F-18
1 2 3 4 5 15 24
1 2 3 4 5 15 24
For some reason the data remains the same, unless printed using BitConverter.
What am I not understanding?
Update
New code produces the following output:
10000000 01000000 11000000 00100000 10100000 11110000 00011000
00000001 00000010 00000011 00000100 00000101 00001111 00011000
01-02-03-04-05-0F-18
80-40-C0-20-A0-F0-18
1 2 3 4 5 15 24
128 64 192 32 160 240 24
But as I have been told now, my method is incorrect anyway because I should invert the bytes
and not the bits?
This hardware developer I'm working with told me to invert the bits because he cannot read the data.
Context where I'm using this
The application that will use this does not really work with numbers.
I'm supposed to save a stream of bits to file where
1 = white and 0 = black.
They represent pixels of a bitmap 256x64.
byte 0 to byte 31 represents the first row of pixels
byte 32 to byte 63 the second row of pixels.
I have code that outputs these bits... but the developer is telling
me they are in the wrong order... He says the bytes are fine but the bits are not.
So I'm left confused :p
No. Endianness refers to the order of bytes, not bits. Big endian systems store the most-significant byte first and little-endian systems store the least-significant first. The bits within a byte remain in the same order.
Your ToBig() function is returning the original data rather than the bit-swapped data, it seems.
Your method may be correct at this point. There are different meanings of endianness, and it depends on the hardware.
Typically, it's used for converting between computing platforms. Most CPU vendors (now) use the same bit ordering, but different byte ordering, for different chipsets. This means, that, if you are passing a 2-byte int from one system to another, you leave the bits alone, but swap bytes 1 and 2, ie:
int somenumber -> byte[2]: somenumber[high],somenumber[low] ->
byte[2]: somenumber[low],somenumber[high] -> int newNumber
However, this isn't always true. Some hardware still uses inverted BIT ordering, so what you have may be correct. You'll need to either trust your hardware dev. or look into it further.
I recommend reading up on this on Wikipedia - always a great source of info:
http://en.wikipedia.org/wiki/Endianness
Your ToBig method has a bug.
At the end:
invertedBits.CopyTo(data, i);
}
return data;
You need to change that to:
byte[] newData = new byte[data.Length];
invertedBits.CopyTo(newData, i);
}
return newData;
You're resetting your input data, so you're receiving both arrays inverted. The problem is that arrays are reference types, so you can modify the original data.
As greyfade already said, endianness is not about bit ordering.
The reason that your code doesn't do what you expect, is that the ToBig method changes the array that you send to it. That means that after calling the method the array is inverted, and data and inverted are just two references pointing to the same array.
Here's a corrected version of the method.
private static byte[] ToBig(byte[] data) {
byte[] result = new byte[data.length];
for (int i = 0; i < data.Length; i++) {
var bits = new BitArray(new byte[] { data[i] });
var invertedBits = new BitArray(bits.Count);
int x = 0;
for (int p = bits.Count - 1; p >= 0; p--) {
invertedBits[x] = bits[p];
x++;
}
invertedBits.CopyTo(result, i);
}
return result;
}
Edit:
Here's a method that changes endianness for a byte array:
static byte[] ConvertEndianness(byte[] data, int wordSize) {
if (data.Length % wordSize != 0) throw new ArgumentException("The data length does not divide into an even number of words.");
byte[] result = new byte[data.Length];
int offset = wordSize - 1;
for (int i = 0; i < data.Length; i++) {
result[i + offset] = data[i];
offset -= 2;
if (offset < -wordSize) {
offset += wordSize * 2;
}
}
return result;
}
Example:
byte[] data = { 1,2,3,4,5,6 };
byte[] inverted = ConvertEndianness(data, 2);
Console.WriteLine(BitConverter.ToString(inverted));
Output:
02-01-04-03-06-05
The second parameter is the word size. As endianness is the ordering of bytes in a word, you have to specify how large the words are.
Edit 2:
Here is a more efficient method for reversing the bits:
static byte[] ReverseBits(byte[] data) {
byte[] result = new byte[data.Length];
for (int i = 0; i < data.Length; i++) {
int b = data[i];
int r = 0;
for (int j = 0; j < 8; j++) {
r <<= 1;
r |= b & 1;
b >>= 1;
}
result[i] = (byte)r;
}
return result;
}
One big problem I see is ToBig changes the contents of the data[] array that is passed to it.
You're calling ToBig on an array named data, then assigning the result to inverted, but since you didn't create a new array inside ToBig, you modified both arrays, then you proceed to treat the arrays data and inverted as different when in reality they are not.

Categories

Resources