fork download
  1. #include <string.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6.  
  7. /*
  8. [20:18:40]{main}z@w:/tmp
  9. $ gcc -std=c11 src.c -o src && ./src pack 1 0 1 0 1 0
  10. 8324
  11. [20:18:43]{main}z@w:/tmp
  12. $ gcc -std=c11 src.c -o src && ./src unpack 8324
  13. SignalPower=1 WorkingGroup=0 IsBlocked=1 ChargeLevel=0 HasVideoCall=1 ConnectionType=0
  14.  
  15. */
  16.  
  17. struct __attribute__((packed)) TMobileIdentifier {
  18. unsigned int ConnectionType : 2;
  19. unsigned int HasVideoCall : 1;
  20. unsigned int ChargeLevel : 3;
  21. unsigned int Reserved6 : 1;
  22. unsigned int IsBlocked : 1;
  23. unsigned int Reserved8 : 1;
  24. unsigned int WorkingGroup : 4;
  25. unsigned int SignalPower : 3;
  26. };
  27.  
  28. void die(const char* msg) {
  29. fprintf(stderr, "%s\n", msg);
  30. exit(1);
  31. }
  32.  
  33. void shift(int* argc, char*** argv) {
  34. if (*argc == 0) {
  35. die("no arguments left to shift");
  36. }
  37. (*argc)--;
  38. (*argv)++;
  39. }
  40.  
  41. #define $0 argv[0]
  42. #define $1 argv[1]
  43. #define $2 argv[2]
  44. #define $3 argv[3]
  45. #define $4 argv[4]
  46. #define $5 argv[5]
  47.  
  48. void usage() {
  49. die("Usage: packer [pack|unpack] ...args");
  50. }
  51.  
  52. int main(int argc, char** argv) {
  53. assert(sizeof(struct TMobileIdentifier) <= sizeof(uint16_t) &&
  54. "TMobileIdentifier doesn't fit into uint16_t"
  55. );
  56.  
  57. if (argc == 1) {
  58. usage();
  59. }
  60. shift(&argc, &argv);
  61.  
  62. if (!strcmp($0, "pack")) {
  63. shift(&argc, &argv);
  64. if (argc != 6) {
  65. die("Usage: packer pack SIGNAL_POWER WORKING_GROUP IS_BLOCKED CHARGE_LEVEL HAS_VIDEO_CALL CONNECTION_TYPE");
  66. }
  67. struct TMobileIdentifier data = {};
  68. data.SignalPower = atoi($0);
  69. data.WorkingGroup = atoi($1);
  70. data.IsBlocked = atoi($2);
  71. data.ChargeLevel = atoi($3);
  72. data.HasVideoCall = atoi($4);
  73. data.ConnectionType = atoi($5);
  74. uint16_t encoded = 0;
  75. memcpy(&encoded, &data, sizeof(data));
  76. fprintf(stdout, "%u\n", encoded);
  77. } else if (!strcmp($0, "unpack")) {
  78. shift(&argc, &argv);
  79. if (argc != 1) {
  80. die("Usage: packer unpack NUMBER");
  81. }
  82. uint16_t input = atoi($0);
  83. struct TMobileIdentifier decoded;
  84. memcpy(&decoded, &input, sizeof(input));
  85. #define OUTPUT_FIELD(NAME) #NAME, decoded.NAME
  86. fprintf(stdout, "%s=%u\t%s=%u\t%s=%u\t%s=%u\t%s=%u\t%s=%u\n",
  87. OUTPUT_FIELD(SignalPower),
  88. OUTPUT_FIELD(WorkingGroup),
  89. OUTPUT_FIELD(IsBlocked),
  90. OUTPUT_FIELD(ChargeLevel),
  91. OUTPUT_FIELD(HasVideoCall),
  92. OUTPUT_FIELD(ConnectionType)
  93. );
  94. #undef OUTPUT_FIELD
  95. } else {
  96. usage();
  97. }
  98. }
Runtime error #stdin #stdout #stderr 0s 2164KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Usage: packer [pack|unpack] ...args