I figured out how to pack my bits being a ushort 16bits, my enums are 1 - 13 so they should all fit. Problem is I know I can unpack in a faster fashion then what I was doing and quite shamefully I didn't want to post my horrid code. Any insight would be appreciative. My Push isn't a string it pushes to a byte array so string would be broken down into individual bytes. My ushort is broken down into 2 bytes a float is broken down into 4 bytes etc etc. Here is an image of what I am trying to accomplish..
Revised Code Statements 11/27/2018 11:47pm
Enums.cs
public enum PacketFlags
{
None = 0x1,
Nat = 0x2,
Hb = 0x4,
Dat = 0x8,
Dscvr = 0x16,
Status = 0x20,
Conn = 0x40,
Finn = 0x80,
ReliableOrdered = 0x100,
Sequenced = 0x200,
NotFragged = 0x400,
Frag = 0x800,
Fragout = 0x1000,
}
Methods In Question
public void WriteHeader()
{
Count = Ptr;
var flag = Fragmented | Proto | Flag;
var field = (ushort)flag;
Ptr = 0;
Push(field);
Push(_id);
}
public void ReadHeader()
{
Ptr = 0;
var header = PullUShort();
var flags = (PacketFlags)header;
SetFlag(flags);
SetProto(flags);
SetFrag(flags);
_id = PullUShort();
}
private void SetFlag(PacketFlags flags)
{
//Set Flag
if((flags & PacketFlags.None) != 0)
{
Flag = PacketFlags.None;
}
if ((flags & PacketFlags.Nat) != 0)
{
Flag = PacketFlags.Nat;
}
if ((flags & PacketFlags.Hb) != 0)
{
Flag = PacketFlags.Hb;
}
if ((flags & PacketFlags.Dat) != 0)
{
Flag = PacketFlags.Dat;
}
if ((flags & PacketFlags.Dscvr) != 0)
{
Flag = PacketFlags.Dscvr;
}
if ((flags & PacketFlags.Status) != 0)
{
Flag = PacketFlags.Status;
}
if ((flags & PacketFlags.Conn) != 0)
{
Flag = PacketFlags.Conn;
}
if ((flags & PacketFlags.Finn) != 0)
{
Flag = PacketFlags.Finn;
}
}
private void SetProto(PacketFlags flags)
{
if ((flags & PacketFlags.ReliableOrdered) != 0)
{
Proto = PacketFlags.ReliableOrdered;
}
if ((flags & PacketFlags.Sequenced) != 0)
{
Flag = PacketFlags.Sequenced;
}
}
private void SetFrag(PacketFlags flags)
{
if ((flags & PacketFlags.NotFragged) != 0)
{
Flag = PacketFlags.NotFragged;
}
if ((flags & PacketFlags.Frag) != 0)
{
Flag = PacketFlags.Frag;
}
if ((flags & PacketFlags.Fragout) != 0)
{
Flag = PacketFlags.Fragout;
}
}
Please note I am on .Net 3.5 and this is for a networking solution. Enum.HasValue uses reflection if the application is processing 40k + packets a second and running that method compaired to a bitwise operation its slow. I am not looking for easy I would like performance.
You're trying to specify your flags using bit positions. Its easier if you just use the values at those bits.
[Flags]
public enum PacketFlags : ushort
{
None = 0x01, // this is the same as 1 << 1 = 1
Nat = 0x02, // this is the same as 1 << 2 = 2
Hb = 0x04, // this is the same as 1 << 3 = 4
Dat = 0x08,
Dscvr = 0x10,
Status = 0x20, // this is the same as 1 << 6 = 32
Conn = 0x40,
Finn = 0x80,
}
First, 'none' is typically assigned zero, but that aside, let's assume your flags will always have a bit set, even if no flags are set.
Two, I specified the flag values in hexadecimal, but this isn't necessary. You can use simple base-10 numbers if you prefer.
Three, all the [Flags] attribute does is change what happens when you format your enum to a string. Go ahead and try it. OR some flags together, then call .ToString() on it. Then remove the attribute, and notice the difference. It's handy, but doesn't do anything terribly important.
Now, to your question:
Packing is as simple as bitwise-ORing them together:
var flag = PacketFlags.Nat | PacketFlags.Hb;
You can now cast this to a ushort, when you want the number representation of your flags:
var imaNumber = (ushort)flag; // equals 0x06.
You can see the [Flags] attribute in action:
var inEnglish = flag.ToString(); // contains: "Nat, Hb"
Unpacking is as simple as casting the ushort value to PacketFlags:
var unpacked = (PacketFlags)imaNumber;
You can then check if a particular flag is set using Enum.HasFlags.
This answer is meant to get you started in the right direction. I can amend it as necessary in response to feedback. See where you can take it first.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
In order to check hihest bit is on I use code:
byte data = 0x88 ;
bool is_on= ((data & 0x80) == 0x80);
How to do this in more elegant and C# way ?
public static bool Get(byte b, int position)
{
if (position > 7)
throw new ArgumentException();
return ((b & (byte)(1 << position)) != 0);
}
Since you're checking a bit, the only thing I might do is write out the literal so you can see the individual bits, like this:
int mask = 0b1000_0000;
byte data = 0x88 ;
bool is_on= ((data & mask) == mask);
I might further abstract this as a method:
public static bool MatchesMask(this int data, int mask)
{
return (data&mask)==mask;
}
So I could call it like this:
int mask = 0b1000_0000;
byte data = 0x88 ;
bool is_on = data.MatchesMask(mask);
If you are dealing with bit setting and getting consider some auxiliary classes to help you. Look at the Flag structure below
Usage
You initialize a Flag with a mask Flag flag = 0x20, or set a specific bit Flag flag = Flag.Bit(5).
You poll a bit with flag.Get(value) and you set a bit with value = flag.Set(value); to set to 1, and value = flag.Set(value, false); to set it 0.
Test Output
10110011 & 00100000 = True
10010011 & 00100000 = False
Code
public struct Flag
{
readonly byte mask;
public Flag(byte mask)
{
this.mask=mask;
}
public byte Mask => this.mask;
public static Flag Bit(int position)
=> new Flag((byte)(1<<position));
public static implicit operator byte(Flag bit) => bit.mask;
public static implicit operator Flag(byte mask) => new Flag(mask);
public bool Get(byte value) => (value & mask)!=0;
public byte Set(byte value, bool bit = true)
{
if (bit)
{
return (byte)(value | mask);
}
else
{
return (byte)(value & ~mask);
}
}
}
static class Program
{
public static string Bin(this byte data)
=> Convert.ToString(data, 2).PadLeft(8, '0');
static void Main(string[] args)
{
byte value = 0xB3;
Flag flag = 0x20;
// or alernativly
// var flag = Flag.Bit(6); // mask = 0b0010000
Console.WriteLine($"{Bin(value)} & {Bin(flag.Mask)} = {flag.Get(value)}");
// not set the bit to 0
value = flag.Set(value, false);
Console.WriteLine($"{Bin(value)} & {Bin(flag.Mask)} = {flag.Get(value)}");
}
}
References
Set a specific bit in an int
I have to define a communication protocol and I want to use a bitfield to store some logic values.
I'm working on the both systems: the sender: a device and a .Net software as receiver.
On the firmware side, I defined as usually a bitfield struct like:
struct __attribute__((__packed__)) BitsField
{
// Logic values
uint8_t vesselPresenceSw: 1;
uint8_t drawerPresenceSw: 1;
uint8_t pumpState: 1;
uint8_t waterValveState: 1;
uint8_t steamValveState: 1;
uint8_t motorDriverState: 1;
// Unused
uint8_t unused_0: 1;
uint8_t unused_1: 1;
};
How I can define a same structure on the software side that support a bytes deserialization to build the struct itself?
I'm afraid there is no direct C# equivalent to C-style bitfield structs.
C# is capable, to a limited extent, of approximating C-style unions by using FieldOffset attributes. These explicit layout attributes allow you to specify exact and potentially overlapping field offsets. Unfortunately, that doesn't even get you halfway there: the offsets must be specified in bytes rather than bits, and you cannot enforce a specific width when reading or writing overlapping fields.
The closest C# comes to natively supporting bitfields is probably flag-based enum types. You may find this sufficient, provided you don't need more than 64 bits. Start by declaring an enum based on the smallest unsigned type that will fit all your flags:
[Flags]
public enum BitFields : byte {
None = 0,
VesselPresenceSw = 1 << 0,
DrawerPresenceSw = 1 << 1,
PumpState = 1 << 2,
WaterValveState = 1 << 3,
SteamValveState = 1 << 4,
MotorDriverState = 1 << 5
}
The named items can have any value assigned to them that fits within the underlying type (byte in this case), so one item could represent multiple bits if you wanted it to. Note that if you want to interop directly with a C-style bitfield, your first value should start at the most significant bit rather than the least.
To use your flags, just declare a variable or field of your new type and perform whatever bitwise operations you need:
BitFields bits = BitFields.None;
bits |= BitFields.VesselPresenceSw | BitFields.PumpState;
bits &= ~BitFields.VesselPresenceSw;
// etc.
On the upside, enums declared with [Flags] are nicely formatted when displayed in the debugger or converted to strings. For example, if you were to print the expression BitFields.VesselPresenceSw | BitFields.PumpState, you would get the text DrawerPresenceSw, PumpState.
There is a caveat: the storage for an enum will accept any value that fits within the underlying type. It would be perfectly legal to write:
BitFields badBits = (BitFields)0xFF;
This sets all 8 bits of the byte-sized enumeration, but our named values only cover 6 bits. Depending on your requirements, you may want to declare a constant that encompasses only the 'legal' flags, which you could & against.
If you need anything richer than that, there is a framework-level 'bitfield' data structure called BitArray. However, BitArray is a reference type that uses a managed int[] for storage. It's not going to help you if want a struct that you could use for interop purposes or any kind of memory mapping.
Please see an example,
C code,
struct example_bit_field
{
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char two_bits : 2;
unsigned char four_bits : 4;
}
and C# equivalent,
[BitFieldNumberOfBitsAttribute(8)]
struct ExampleBitField : IBitField
{
[BitFieldInfo(0, 1)]
public bool Bit1 { get; set; }
[BitFieldInfo(1, 1)]
public byte Bit2 { get; set; }
[BitFieldInfo(2, 2)]
public byte TwoBits { get; set; }
[BitFieldInfo(4, 4)]
public byte FourBits { get; set; }
}
Source :- https://www.codeproject.com/Articles/1095576/Bit-Field-in-Csharp-using-struct
You can try mimic such a struct. It seems, that you want to use it in the interop (say, C routine exchange data with C# program). Since you have logic values, let expose them as bool:
using System.Runtime.InteropServices;
...
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyBitsField {
private Byte m_Data; // We actually store Byte
public MyBitsField(Byte data) {
m_Data = data;
}
private bool GetBit(int index) {
return (m_Data & (1 << index)) != 0;
}
private void SetBit(int index, bool value) {
byte v = (byte)(1 << index);
if (value)
m_Data |= v;
else
m_Data = (byte) ((m_Data | v) ^ v);
}
public bool vesselPresenceSw {
get { return GetBit(0); }
set { SetBit(0, value); }
}
...
public bool motorDriverState {
get { return GetBit(5); }
set { SetBit(5, value); }
}
}
Usage:
var itemToSend = new MyBitsField() {
vesselPresenceSw = false,
motorDriverState = true,
};
In the meantime, I had a similar idea #Dmitry.
I found the following solution using FieldOffset attribute.
Working well without additional code. I think it's acceptable.
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct LiveDataBitField
{
// Where the values are effectively stored
public byte WholeField { get; private set; }
public bool VesselPresenceSw
{
get => (WholeField & 0x1) > 0;
set
{
if (value)
{
WholeField |= 1;
}
else
{
WholeField &= 0xfE;
}
}
}
public bool DrawerPresenceSw
{
get => (WholeField & 0x2) >> 1 > 0;
set
{
if (value)
{
WholeField |= (1 << 1);
}
else
{
WholeField &= 0xFD;
}
}
}
public bool PumpState
{
get => (WholeField & 0x4) >> 2 > 0;
set
{
if (value)
{
WholeField |= (1 << 2);
}
else
{
WholeField &= 0xFB;
}
}
}
public bool WaterValveState
{
get => (WholeField & 0x8) >> 3 > 0;
set
{
if (value)
{
WholeField |= (1 << 3);
}
else
{
WholeField &= 0xF7;
}
}
}
public bool SteamValveState
{
get => (WholeField & 0x10) >> 4 > 0;
set
{
if (value)
{
WholeField |= (1 << 4);
}
else
{
WholeField &= 0xEF;
}
}
}
public bool MotorDriverState
{
get => (WholeField & 0x20) >> 5 > 0;
set
{
if (value)
{
WholeField |= (1 << 5);
}
else
{
WholeField &= 0xDF;
}
}
}
}
To deserialize a byte array to struct you can use:
public static object ReadStruct(byte[] data, Type type)
{
var pinnedPacket = GCHandle.Alloc(data, GCHandleType.Pinned);
var obj = Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), type);
pinnedPacket.Free();
return obj;
}
There has lots of example of convert CIDR to ip range. But I want to know how can I use start/end ip address to generate a/some cidr in C#?
for example:
I have start ip address(192.168.0.1) and end ip address(192.168.0.254). So use these two address to generate cidr list {192.168.0.0/31, 192.168.0.2/32}. Is there any C# code example?
CIDR class with static methods to split an IP range into a minimal set of disjoint CIDR ranges, which cover exactly the original IP range.
The split methods (the "real" one working on BigIntegers doing the actual work, and the wrapper for IP addresses and CIDR creation) are at the bottom.
Use with foreach (IPRangeToCidr.CIDR c in IPRangeToCidr.CIDR.split(first, last)) ...
Requires System.Numerics.dll in the references.
using System;
using System.Numerics;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
namespace IPRangeToCidr {
public struct CIDR {
private IPAddress address;
private uint network_length, bits;
public CIDR(IPAddress address, uint network_length) {
this.address = address;
this.network_length = network_length;
this.bits = AddressFamilyBits(address.AddressFamily);
if (network_length > bits) {
throw new ArgumentException("Invalid network length " + network_length + " for " + address.AddressFamily);
}
}
public IPAddress NetworkAddress {
get { return address; }
}
public IPAddress LastAddress {
get { return IPAddressAdd(address, (new BigInteger(1) << (int) HostLength) - 1); }
}
public uint NetworkLength {
get { return network_length; }
}
public uint AddressBits {
get { return bits; }
}
public uint HostLength {
get { return bits - network_length; }
}
override public String ToString() {
return address.ToString() + "/" + NetworkLength.ToString();
}
public String ToShortString() {
if (network_length == bits) return address.ToString();
return address.ToString() + "/" + NetworkLength.ToString();
}
/* static helpers */
public static IPAddress IPAddressAdd(IPAddress address, BigInteger i) {
return IPFromUnsigned(IPToUnsigned(address) + i, address.AddressFamily);
}
public static uint AddressFamilyBits(AddressFamily family) {
switch (family) {
case AddressFamily.InterNetwork:
return 32;
case AddressFamily.InterNetworkV6:
return 128;
default:
throw new ArgumentException("Invalid address family " + family);
}
}
private static BigInteger IPToUnsigned(IPAddress addr) {
/* Need to reverse addr bytes for BigInteger; prefix with 0 byte to force unsigned BigInteger
* read BigInteger bytes as: bytes[n] bytes[n-1] ... bytes[0], address is bytes[0] bytes[1] .. bytes[n] */
byte[] b = addr.GetAddressBytes();
byte[] unsigned = new byte[b.Length + 1];
for (int i = 0; i < b.Length; ++i) {
unsigned[i] = b[(b.Length - 1) - i];
}
unsigned[b.Length] = 0;
return new BigInteger(unsigned);
}
private static byte[] GetUnsignedBytes(BigInteger unsigned, uint bytes) {
/* reverse bytes again. check that now higher bytes are actually used */
if (unsigned.Sign < 0) throw new ArgumentException("argument must be >= 0");
byte[] data = unsigned.ToByteArray();
byte[] result = new byte[bytes];
for (int i = 0; i < bytes && i < data.Length; ++i) {
result[bytes - 1 - i] = data[i];
}
for (uint i = bytes; i < data.Length; ++i) {
if (data[i] != 0) throw new ArgumentException("argument doesn't fit in requested number of bytes");
}
return result;
}
private static IPAddress IPFromUnsigned(BigInteger unsigned, System.Net.Sockets.AddressFamily family) {
/* IPAddress(byte[]) constructor picks family from array size */
switch (family) {
case System.Net.Sockets.AddressFamily.InterNetwork:
return new IPAddress(GetUnsignedBytes(unsigned, 4));
case System.Net.Sockets.AddressFamily.InterNetworkV6:
return new IPAddress(GetUnsignedBytes(unsigned, 16));
default:
throw new ArgumentException("AddressFamily " + family.ToString() + " not supported");
}
}
/* splits set [first..last] of unsigned integers into disjoint slices { x,..., x + 2^k - 1 | x mod 2^k == 0 }
* covering exaclty the given set.
* yields the slices ordered by x as tuples (x, k)
* This code relies on the fact that BigInteger can't overflow; temporary results may need more bits than last is using.
*/
public static IEnumerable<Tuple<BigInteger, uint>> split(BigInteger first, BigInteger last) {
if (first > last) yield break;
if (first < 0) throw new ArgumentException();
last += 1;
/* mask == 1 << len */
BigInteger mask = 1;
uint len = 0;
while (first + mask <= last) {
if ((first & mask) != 0) {
yield return new Tuple<BigInteger, uint>(first, len);
first += mask;
}
mask <<= 1;
++len;
}
while (first < last) {
mask >>= 1;
--len;
if ((last & mask) != 0) {
yield return new Tuple<BigInteger, uint>(first, len);
first += mask;
}
}
}
public static IEnumerable<CIDR> split(IPAddress first, IPAddress last) {
if (first.AddressFamily != last.AddressFamily) {
throw new ArgumentException("AddressFamilies don't match");
}
AddressFamily family = first.AddressFamily;
uint bits = AddressFamilyBits(family); /* split on numbers returns host length, CIDR takes network length */
foreach (Tuple<BigInteger, uint> slice in split(IPToUnsigned(first), IPToUnsigned(last))) {
yield return new CIDR(IPFromUnsigned(slice.Item1, family), bits - slice.Item2);
}
}
}
}
It is difficult to determine the what exactly is being asked here (the CIDR list you give doesn't seem to correspond with the given input addresses), however the following code will allow you to find the smallest single CIDR that contains the specified start and end addresses.
You need to first convert the start and end IP addresses into 32 bit integers (e.g. 192.168.0.1 becomes 0xc0a80001), then apply the following algorithm:
var startAddr = 0xc0a80001; // 192.168.0.1
var endAddr = 0xc0a800fe; // 192.168.0.254
// Determine all bits that are different between the two IPs
var diffs = startAddr ^ endAddr;
// Now count the number of consecutive zero bits starting at the most significant
var bits = 32;
var mask = 0;
while (diffs != 0)
{
// We keep shifting diffs right until it's zero (i.e. we've shifted all the non-zero bits off)
diffs >>= 1;
// Every time we shift, that's one fewer consecutive zero bits in the prefix
bits--;
// Accumulate a mask which will have zeros in the consecutive zeros of the prefix and ones elsewhere
mask = (mask << 1) | 1;
}
// Construct the root of the range by inverting the mask and ANDing it with the start address
var root = startAddr & ~mask;
// Finally, output the range
Console.WriteLine("{0}.{1}.{2}.{3}/{4}", root >> 24, (root >> 16) & 0xff, (root >> 8) & 0xff, root & 0xff, bits);
Running it on the two addresses in your question gives:
192.168.0.0/24
Necromancing.
No, there wasn't, and I don't understand why people keep upvoting wrong answers.
Here's the code for IP-range to CIDR & vice-versa:
// https://dev.maxmind.com/geoip/
// https://stackoverflow.com/questions/461742/how-to-convert-an-ipv4-address-into-a-integer-in-c
public static string IPrange2CIDR(string ip1, string ip2)
{
uint startAddr = IP2num(ip1);
uint endAddr = IP2num(ip2);
// uint startAddr = 0xc0a80001; // 192.168.0.1
// uint endAddr = 0xc0a800fe; // 192.168.0.254
// uint startAddr = System.BitConverter.ToUInt32(System.Net.IPAddress.Parse(ip1).GetAddressBytes(), 0);
// uint endAddr = System.BitConverter.ToUInt32(System.Net.IPAddress.Parse(ip2).GetAddressBytes(), 0);
if (startAddr > endAddr)
{
uint temp = startAddr;
startAddr = endAddr;
endAddr = temp;
}
// uint diff = endAddr - startAddr -1;
// int bits = 32 - (int)System.Math.Ceiling(System.Math.Log10(diff) / System.Math.Log10(2));
// return ip1 + "/" + bits;
uint diffs = startAddr ^ endAddr;
// Now count the number of consecutive zero bits starting at the most significant
int bits = 32;
// int mask = 0;
// We keep shifting diffs right until it's zero (i.e. we've shifted all the non-zero bits off)
while (diffs != 0)
{
diffs >>= 1;
bits--; // Every time we shift, that's one fewer consecutive zero bits in the prefix
// Accumulate a mask which will have zeros in the consecutive zeros of the prefix and ones elsewhere
// mask = (mask << 1) | 1;
}
string res = ip1 + "/" + bits;
System.Console.WriteLine(res);
return res;
}
// https://www.digitalocean.com/community/tutorials/understanding-ip-addresses-subnets-and-cidr-notation-for-networking
public static void CIDR2IP(string IP)
{
string[] parts = IP.Split('.', '/');
uint ipnum = (System.Convert.ToUInt32(parts[0]) << 24) |
(System.Convert.ToUInt32(parts[1]) << 16) |
(System.Convert.ToUInt32(parts[2]) << 8) |
System.Convert.ToUInt32(parts[3]);
int maskbits = System.Convert.ToInt32(parts[4]);
uint mask = 0xffffffff;
mask <<= (32 - maskbits);
uint ipstart = ipnum & mask;
uint ipend = ipnum | (mask ^ 0xffffffff);
string fromRange = string.Format("{0}.{1}.{2}.{3}", ipstart >> 24, (ipstart >> 16) & 0xff, (ipstart >> 8) & 0xff, ipstart & 0xff);
string toRange = string.Format("{0}.{1}.{2}.{3}", ipend >> 24, (ipend >> 16) & 0xff, (ipend >> 8) & 0xff, ipend & 0xff);
System.Console.WriteLine(fromRange + " - " + toRange);
}
public static uint IP2num(string ip)
{
string[] nums = ip.Split('.');
uint first = System.UInt32.Parse(nums[0]);
uint second = System.UInt32.Parse(nums[1]);
uint third = System.UInt32.Parse(nums[2]);
uint fourth = System.UInt32.Parse(nums[3]);
return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
public static void Test()
{
string IP = "5.39.40.96/27";
// IP = "88.84.128.0/19";
CIDR2IP(IP);
// IPrange2CIDR("88.84.128.0", "88.84.159.255");
IPrange2CIDR("5.39.40.96", "5.39.40.127");
System.Console.WriteLine(System.Environment.NewLine);
System.Console.WriteLine(" --- Press any key to continue --- ");
System.Console.ReadKey();
}
I use this for IpV4, let me know if there is a problem in it.
You can find the extraction source code from the following link:
https://blog.ip2location.com/knowledge-base/how-to-convert-ip-address-range-into-cidr/
using System;
using System.Collections.Generic;
using System.Net;
namespace ConsoleApp
{
public class IPNetwork
{
private readonly long _firstIpAddress;
private readonly long _lastIpAddress;
public static IPNetwork[] FromIpRange(IPAddress firstIpAddress, IPAddress lastIpAddress)
=> FromIpRange(IpAddressToLong(firstIpAddress), IpAddressToLong(lastIpAddress));
public static IPNetwork[] FromIpRange(long firstIpAddress, long lastIpAddress)
{
var result = new List<IPNetwork>();
while (lastIpAddress >= firstIpAddress)
{
byte maxSize = 32;
while (maxSize > 0)
{
long mask = IMask(maxSize - 1);
long maskBase = firstIpAddress & mask;
if (maskBase != firstIpAddress)
break;
maxSize--;
}
double x = Math.Log(lastIpAddress - firstIpAddress + 1) / Math.Log(2);
byte maxDiff = (byte)(32 - Math.Floor(x));
if (maxSize < maxDiff)
{
maxSize = maxDiff;
}
var ipAddress = IpAddressFromLong(firstIpAddress);
result.Add(new IPNetwork(ipAddress, maxSize));
firstIpAddress += (long)Math.Pow(2, 32 - maxSize);
}
return result.ToArray();
}
private static long IMask(int s)
{
return (long)(Math.Pow(2, 32) - Math.Pow(2, 32 - s));
}
public static long IpAddressToLong(IPAddress ipAddress)
{
var bytes = ipAddress.GetAddressBytes();
return ((long)bytes[0] << 24) | ((long)bytes[1] << 16) | ((long)bytes[2] << 8) | bytes[3];
}
public static IPAddress IpAddressFromLong(long ipAddress)
=> new IPAddress((uint)IPAddress.NetworkToHostOrder((int)ipAddress));
public IPNetwork(IPAddress prefix, int prefixLength = 32)
{
if (prefix.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
throw new NotSupportedException("IPv6 is not supported");
Prefix = prefix;
PrefixLength = prefixLength;
var mask = (uint)~(0xFFFFFFFFL >> prefixLength);
_firstIpAddress = IpAddressToLong(Prefix) & mask;
_lastIpAddress = _firstIpAddress | ~mask;
}
public static IPNetwork Parse(string value)
{
try
{
var parts = value.Split('/');
return new IPNetwork(IPAddress.Parse(parts[0]), int.Parse(parts[1]));
}
catch
{
throw new FormatException($"Could not parse IPNetwork from {value}");
}
}
public override string ToString() => $"{Prefix}/{PrefixLength}";
public IPAddress Prefix { get; }
public int PrefixLength { get; }
public IPAddress LastAddress => IpAddressFromLong(_lastIpAddress);
public IPAddress FirstAddress => IpAddressFromLong(_firstIpAddress);
public long Total => _lastIpAddress - _firstIpAddress + 1;
}
}
Usage 1:
var startAddress = IPAddress.Parse("192.168.0.0");
var endAddress = IPAddress.Parse("192.168.0.255");
foreach (var item in IPNetwork.FromIpRange(startAddress, endAddress))
Console.WriteLine(item);
Result
192.168.0.0/24
Usage 2:
var startAddress = IPAddress.Parse("192.168.0.1");
var endAddress = IPAddress.Parse("192.168.0.254");
foreach (var item in IPNetwork.FromIpRange(startAddress, endAddress))
Console.WriteLine(item);
Result:
192.168.0.1/32
192.168.0.2/31
192.168.0.4/30
192.168.0.8/29
192.168.0.16/28
192.168.0.32/27
192.168.0.64/26
192.168.0.128/26
192.168.0.192/27
192.168.0.224/28
192.168.0.240/29
192.168.0.248/30
192.168.0.252/31
192.168.0.254/32
I would recommend the use of IPNetwork Library https://github.com/lduchosal/ipnetwork.
As of version 2, it supports IPv4 and IPv6 as well.
Supernet
IPNetwork network = IPNetwork.Parse("192.168.0.1");
IPNetwork network2 = IPNetwork.Parse("192.168.0.254");
IPNetwork ipnetwork = IPNetwork.Supernet(network, network2);
Console.WriteLine("Network : {0}", ipnetwork.Network);
Console.WriteLine("Netmask : {0}", ipnetwork.Netmask);
Console.WriteLine("Broadcast : {0}", ipnetwork.Broadcast);
Console.WriteLine("FirstUsable : {0}", ipnetwork.FirstUsable);
Console.WriteLine("LastUsable : {0}", ipnetwork.LastUsable);
Console.WriteLine("Usable : {0}", ipnetwork.Usable);
Console.WriteLine("Cidr : {0}", ipnetwork.Cidr);
Output
Network : 192.168.0.0
Netmask : 255.255.255.0
Broadcast : 192.168.0.255
FirstUsable : 192.168.0.1
LastUsable : 192.168.0.254
Usable : 254
Cidr : 24
Have fun !
I found this C code and converted it into C# and it's working now.
I have a 16-bit int, and I am trying to exchange the values of some of the individual bit components.
For instance:
swap the values of the 3rd and 4th bit.
swap the values of the 5th and 6th bit.
I also have to deal with more complicated chains of value transference.
move the value of the 2nd bit to the 3rd bit
move the value of the 3rd bit to the 1st bit
move the value of the 1st bit to the 4th bit
move the value of the 4th bit to the 2nd bit.
Is there a sensible way to do this? The bits aren't always adjacent, so a rotate doesn't seem particularly viable. Right now, all I can think to do is rebuild the int bit-by-bit (via successive &s + >>s), but that doesn't seem particularly effective.
I've got this right now:
// bit 2 to bit 3
temp_shape = 0;
temp_shape = l_shape & NegXFace;
temp_shape >>= 1;
resultShape |= temp_shape;
// bit 3 to bit 1
temp_shape = 0;
temp_shape = l_shape & PosYFace;
temp_shape <<= 2;
resultShape |= temp_shape;
// bit 1 to bit 4
temp_shape = 0;
temp_shape = l_shape & PosXFace;
temp_shape >>= 2;
resultShape |= temp_shape;
// bit 4 to bit 2
temp_shape = 0;
temp_shape = l_shape & PosYFace;
temp_shape <<= 2;
resultShape |= temp_shape;
// bits 5 and 6
temp_shape = 0;
temp_shape = l_shape & (PosZFace | NegZFace);
resultShape |= temp_shape;
well you can check to see if the bits are the same, and if they are the same do nothing. And if they are different, you can flip both of them at the same time by XORing by the appropriate bit mask (eg 0001100 for 3rd and 4th bit). I'm not really sure how "efficient" this will end up being though.
Assuming:
[Flags]
public enum MyBits
{
Bit1 = 0x01,
Bit2 = 0x02,
Bit3 = 0x04,
Bit4 = 0x08,
Bit5 = 0x10,
Bit6 = 0x20
}
Then:
public MyBits SwitchBits(MyBits oldBits)
{
// Extracting every bits
bool Bit1 = oldBits.HasFlag(MyBits.Bit1);
bool Bit2 = oldBits.HasFlag(MyBits.Bit2);
bool Bit3 = oldBits.HasFlag(MyBits.Bit3);
bool Bit4 = oldBits.HasFlag(MyBits.Bit4);
bool Bit5 = oldBits.HasFlag(MyBits.Bit5);
bool Bit6 = oldBits.HasFlag(MyBits.Bit6);
MyBits newBits = new MyBits();
// Scrambling the bits
if (Bit4) newBits = newBits | MyBits.Bit1;
if (Bit2) newBits = newBits | MyBits.Bit2;
if (Bit3) newBits = newBits | MyBits.Bit3;
if (Bit1) newBits = newBits | MyBits.Bit4;
if (Bit6) newBits = newBits | MyBits.Bit5;
if (Bit5) newBits = newBits | MyBits.Bit6;
return newBits ;
}
This function can easily swap bit positions pos1 and pos2 of a number n.
1st it checks that the two bits are different or not, if diffrent then it toggled from 1 to 0 or from 0 to 1 and if same then it do nothing and simply return that number
int swap_bit(int n, int pos1, pos2)
{
((n >> pos1) & 1 ) != ( (n >> pos2) & 1 ) ? n = n ^ (( 1 << pos1) |( 1 << pos2)):n;
return n; }
While the other answers were useful, none of the provided methods will work if you ever need to perform more than one of these bit swapping operations in sequence.
Once you've already moved the bits around, it becomes damn near impossible to know which bits started where, unless you want to write logic for every possible permutation of bit swappings.
Instead, you need a method that works for relative position (the bit position of what was originally the 2nd bit), rather than absolute position (the 2nd bit).
Here's how I would do it:
bool[] relFaces = new bool[6];
bool swapBool;
//start relFaces with the absolute faces.
//default value of bool is "FALSE"
if((l_shape & PosXFace) == PosXFace)
{
relFaces[0] = true;
}
if((l_shape & NegXFace) == NegXFace)
{
relFaces[1] = true;
}
if((l_shape & PosYFace) == PosYFace)
{
relFaces[2] = true;
}
if((l_shape & NegYFace) == NegYFace)
{
relFaces[3] = true;
}
if((l_shape & PosZFace) == PosZFace)
{
relFaces[4] = true;
}
if((l_shape & NegZFace) == NegZFace)
{
relFaces[5] = true;
}
// -z >> -x
swapBool = relFaces[1];
relFaces[1] = relFaces[5];
// +x >> -z
relFaces[5] = relFaces[0];
// +z >> +X
relFaces[0] = relFaces[4];
// -X >> +z
relFaces[4] = swapBool;
break;
This code has the advantage of being much easier to understand at a glance, and you don't have to do further operations on bits you're not interested in changing. Finally, as mentioned earlier, this code will work for an arbitrary chain of successive bit-swaps, changing the relative facing (in your case) while maintaining the absolute facing as well.
Do note that you will have to rebuild l_shape once you're done swapping bits.
I am converting a Java class that converts BCD data to ASCII
I am converting it to .Net BCD Convertor
Following is the converted from java but it is giving wrong converted value e.g. for 123456789 it is giving 123456153153
public static string GetStringFromBcd(int[] b)
{
StringBuilder buffer = new StringBuilder();
foreach (var t in b)
{
if ((t & 0x0000000F) == 0x0000000F && ((t >> 4) & 0x0000000F) == 0x0000000F)
{
break;
}
buffer.Append((t & 0x0000000F) + "");
if ((t & 0x000000F0) != 0x000000F0)
{
buffer.Append(((t >> 4) & 0x0000000F) + "");
}
}
}
What could be the problem?
EDIT: ANSWER:
I got the source program where the data has been BCD encoded.
I found that nothing was wrong in that logic, then I discovered the source of the function where the data was converting from network stream to string and later converted to byte/int array.
following is the code
int bytesRead = tcpClient.Receive(message);//, 0, bytetoReadSize);
if (bytesRead == 0)
{
break;
//the client has disconnected from the server
}
//message has successfully been received
data += new ASCIIEncoding().GetString(message, 0, bytesRead);
here is the problem ASCIIEncoding does not convert many encoded character and gives '?'63 instead of those character , when putting 63 in BCD conversion logic it gives 153.
To resolve this error, I Modified the last line and instead of decoding , I am simply casting the received byte to char.
foreach (byte b in message)
{
data += ((char) b);
}
Here's a Similar Question that comes about it a few different ways.
Here's a Site that has an excellent detailed description of what your facing.
It shouldn't be that hard, but processing them as int's is going to be much harder.
Zoned Decimal (BCD) is pretty straight forward to convert, but you have to be careful if your taking files from a mainframe that have been converted via an ASCII transfer. It can still be converted, but the byte values change due to the ebcdic to ascii conversion during the FTP.
If your processing binary files, it's much easier to deal with.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestZoned
{
class Program
{
public static String zoneToString(byte[] zoneBytes)
{
Encoding ascii = Encoding.ASCII;
Encoding ebcdic = Encoding.GetEncoding("IBM037");
byte[] asciiBytes = null;
String str = null;
int zoneLen = zoneBytes.Length;
int i = zoneLen - 1;
int b1 = zoneBytes[i];
b1 = (b1 & 0xf0) >> 4;
switch (b1)
{
case 13:
case 11:
zoneBytes[i] = (byte)(zoneBytes[i] | 0xf0);
asciiBytes = Encoding.Convert(ebcdic, ascii, zoneBytes);
str = "-" + ASCIIEncoding.ASCII.GetString(asciiBytes);
break;
default:
zoneBytes[i] = (byte)(zoneBytes[i] | 0xf0);
asciiBytes = Encoding.Convert(ebcdic, ascii, zoneBytes);
str = ASCIIEncoding.ASCII.GetString(asciiBytes);
break;
}
return (str);
}
static void Main(string[] args)
{
byte[] array = { 0xf0, 0xf0, 0xf1 }; // 001
byte[] pos = { 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; // 123456789
byte[] neg = { 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xd9 }; // -123456789
Console.WriteLine("Converted: {0}", zoneToString(array));
Console.WriteLine("Converted: {0}", zoneToString(pos));
Console.WriteLine("Converted: {0}", zoneToString(neg));
}
}
}
If you wanted to stick to something similar
public static String GetStringFromBcd(byte[] zoneBytes)
{
StringBuilder buffer = new StringBuilder();
int b1 = (zoneBytes[zoneBytes.Length - 1] & 0xf0) >> 4;
if ( (b1 == 13) || (b1 == 11) ) buffer.Append("-");
for (int i = 0; i < zoneBytes.Length; i++)
{
buffer.Append((zoneBytes[i] & 0x0f));
}
return buffer.ToString();
}